Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex sed替换“sed”;func_name(旧参数)";加上;func_name();_Regex_Bash_Sed - Fatal编程技术网

Regex sed替换“sed”;func_name(旧参数)";加上;func_name();

Regex sed替换“sed”;func_name(旧参数)";加上;func_name();,regex,bash,sed,Regex,Bash,Sed,我正在学习使用sed,我搜索了sed并尝试了很多方法,但总有一些场景我没能涵盖 基本上,我需要用func\u name()替换func\u name(旧参数)。这个旧参数可以是很多东西,例如foo(),foo(参数),foo->ptr,foo\u ptr->coent,等等 所以问题是我想删除第一个(和下一个)之间的任何内容 有什么建议吗? 非常感谢您可以使用贪婪的正则表达式,如下所示: func_name\([^)]*\) 因此,您可以使用: sed -i 's/func_name\([^

我正在学习使用
sed
,我搜索了
sed
并尝试了很多方法,但总有一些场景我没能涵盖

基本上,我需要用
func\u name()
替换
func\u name(旧参数)
。这个
旧参数可以是很多东西,例如
foo()
foo(参数)
foo->ptr
foo\u ptr->coent
,等等

所以问题是我想删除第一个
和下一个
之间的任何内容

有什么建议吗?
非常感谢

您可以使用贪婪的正则表达式,如下所示:

func_name\([^)]*\)

因此,您可以使用:

sed -i 's/func_name\([^)]*\)/func_name()/' *.txt
如果您想要更多sed信息,可以查看此

我认为
(.*func\u name\()(?:[^()]*\([^()]*\)*[^]*(\)*(\).
全力以赴

这甚至可以处理
func()+func_name(foo()+goo())+pi()的情况


实时演示:

这对于正则表达式来说有点棘手,因为您试图解析的语言实际上不是正则的。sed不能可靠地做到这一点,因此我们必须求助于Perl

幸运的是,Perl正则表达式可以描述比常规语言更多的语言;特别是,它们支持递归。这样你就可以写作了

perl -pe 'BEGIN { $/ = ""; } s/func_name(\(([^()]|(?1))*\))/func_name()/g' filename
并获得以下行为:

$ cat file
foo, func_name(foo), xyzzy, func_name(foo(),
                                      bar(baz(),
                                          qux()),
                                      quux()), bar();
baz()
$ perl -pe 'BEGIN { $/ = ""; } s/func_name(\(([^()]|(?1))*\))/func_name()/g' file
foo, func_name(), xyzzy, func_name(), bar();
baz()
BEGIN{$/=”;}
将Perl置于slurp模式(因此多行表达式由正则表达式匹配)。然后这个技巧的核心是
(\([^()]|(?1))*\)
捕获组,特别是其中执行递归的
(?1)


从本质上讲,它是这样说的:匹配一个由左括号(
\(
)组成的字符串,后跟任意数量的东西,这些东西要么匹配除括号以外的任何东西(
[^()]
),要么匹配用于捕获组1的正则表达式(
(?1)
),然后是右括号(
\)
)。因为这本身就是用于捕获组1的正则表达式,所以它会递归到自身中,并用平衡括号匹配字符串。

*?
是非贪婪的
sed
不支持非贪婪的
。如果输入是
函数名(测试(1))?您可以(理论上)简单地使用
func\u名称(.*)
,因为
*
在sed中是贪婪的。理论上,因为C代码将包含许多函数调用,因此
func\u名称(.*)
也将匹配
func\u名称(1);测试(2)@hek2mgl是的,我知道,但我基于提供的样本。我的答案集中在非嵌套函数上。Regex对此有限制,并非所有情况都可以涵盖。但这是对OP+1的一条有用的注释这不是嵌套的,而是在同一行上有更多的数据,并且失败了:
echo“func_name(foo)data func_name(old_args)”;sed's/func_name\([^)]*\)/func_name()/”
谢谢,尽管它还不够完美。OP似乎想更改C代码,而C代码中可以包含字符串文字——这可能会失去平衡(例如,
func\u name(“abc”)
)。希望这对OP有效(可能性不坏),但您真正想要的是一种基于libclang的sed等价于C代码。唉,我认为目前还没有这样的事情,写一篇文章会打破这篇文章的范围派斯,你说得对!我目前正在玩
flex
bison
。可能(希望获得更多经验后)我将开始用一个小解析器示例来回答这些问题。可能吧要做到这一点需要一些努力。想象一下必须处理
#定义CLOPAREN)
func#u name(foo-CLOPAREN
。诚然,这是一个极端情况,但如果你计划彻底,那么……这并不是我能想出的最糟糕的诡计。
#定义CONCAT(x,y)x####y
CONCAT(func,name)(x,“abc)”CLOPAREN
,呃?C是一种漂亮的语言。这可以用
flex
bison
来完成,相对容易而且非常可靠。
C
确实漂亮,但解析起来并不难。.不知道。预处理器有其神秘的角落,它以一种你必须实现的方式钉在语言的其余部分上在任何情况下,我可能会从libclang开始,因为他们以前解决了所有这些问题(并且解决得很好)。这可能会减少工作量。语句
while(x>3)
是否应该转换为
while()?如果不是,我们怎么能把函数名和其他涉及语言的语言构建起来呢?显示几行示例输入,因为它总是微不足道的,以找到与你想要的匹配的文本,但是更难在你不想要的文本上得到错误匹配。在你的输入/输出中对它们进行反编码。