Linux 为什么sed会将团队之外的东西作为团队的一部分进行匹配?
我最近尝试使用sed从逗号和换行符分隔的枚举成员生成一系列方法。我遇到了以下行为,这似乎是不直观的:Linux 为什么sed会将团队之外的东西作为团队的一部分进行匹配?,linux,bash,unix,sed,terminal,Linux,Bash,Unix,Sed,Terminal,我最近尝试使用sed从逗号和换行符分隔的枚举成员生成一系列方法。我遇到了以下行为,这似乎是不直观的: $ echo 'Hello,' | sed 's/\(.*\),\?/"Hi \1!"/g' "Hi Hello,!" 在这里,我试图通过\(.*\)将逗号之前的所有内容捕获到一个组中,然后我允许使用带有,\?的可选逗号。我希望这会将\1替换为第一个逗号之前的所有内容,即Hello,但出于某种原因,逗号也会包含在替换中,尽管它不在组中。为什么会这样?默认情况下,正则表达式进行贪婪匹配(从左到右
$ echo 'Hello,' | sed 's/\(.*\),\?/"Hi \1!"/g'
"Hi Hello,!"
在这里,我试图通过
\(.*\)
将逗号之前的所有内容捕获到一个组中,然后我允许使用带有,\?
的可选逗号。我希望这会将\1
替换为第一个逗号之前的所有内容,即Hello
,但出于某种原因,逗号也会包含在替换中,尽管它不在组中。为什么会这样?默认情况下,正则表达式进行贪婪匹配(从左到右),如果最贪婪的匹配不起作用,则进行回溯。因此,在\(.*),\?
的情况下,最贪婪的匹配是将Hello,
与\(.*)
匹配,而对,\?
不匹配
我不知道如何在基本正则表达式中进行非贪婪匹配(这是sed
使用的)。在Perl风格的正则表达式中(sed不使用sed
),在匹配运算符后加一个问号,这样就可以使用类似(.*),
的东西
下一个最好的方法是使用
\([^,]*\),\?
,但它会在看到的第一个逗号处停止匹配。正则表达式默认情况下进行贪婪匹配(从左到右),如果最贪婪的匹配不起作用,则进行回溯。因此,在\(.*),\?
的情况下,最贪婪的匹配是将Hello,
与\(.*)
匹配,而对,\?
不匹配
我不知道如何在基本正则表达式中进行非贪婪匹配(这是sed
使用的)。在Perl风格的正则表达式中(sed不使用sed
),在匹配运算符后加一个问号,这样就可以使用类似(.*),
的东西
下一个最好的方法是使用
\([^,]*\),\?
,但它会在看到的第一个逗号处停止匹配。这是因为sed
正则表达式是贪婪的,?
量词意味着匹配前面标记的0或1--,
因此,在这里,引擎贪婪地匹配到最后,由于?
被?
设置为可选,它也被包含在捕获的组(.*)
中
要获得所需的行为,请删除?
:
% echo 'Hello,' | sed 's/\(.*\),\?/"Hi \1!"/g'
"Hi Hello,!"
% echo 'Hello,' | sed 's/\(.*\),/"Hi \1!"/g'
"Hi Hello!"
这是因为
sed
Regex是贪婪的,?
量词意味着匹配前面的标记--,
中的0或1
因此,在这里,引擎贪婪地匹配到最后,由于?
被?
设置为可选,它也被包含在捕获的组(.*)
中
要获得所需的行为,请删除?
:
% echo 'Hello,' | sed 's/\(.*\),\?/"Hi \1!"/g'
"Hi Hello,!"
% echo 'Hello,' | sed 's/\(.*\),/"Hi \1!"/g'
"Hi Hello!"
谢谢你的回复。结尾的逗号必须是可选的,因为我正在尝试匹配枚举成员,而最后一个没有尾随逗号。感谢您的响应。结尾的逗号必须是可选的,因为我试图匹配枚举成员,而最后一个成员没有尾随逗号。