在Bash正则表达式中,`^`和`$`是指整行还是整个字符串?

5
Linux文档项目中(在Bash手册中没有关于正则表达式元字符的详细信息),元字符^$被定义为匹配行的开头和结尾:^匹配行的开头,$匹配行的结尾。然而,当我尝试时,这是不正确的:
$ string="a
> b
> c"

$ [[ $string =~ ^a ]] && echo BOS match
BOS match

$ [[ $string =~ ^b ]] && echo BOL match
# nothing

手册真的有错吗,还是我漏了什么?


字符串 $string 看起来是什么样子? 显然像这样 "a\nb\nc"。 - rhaport
它们匹配整个字符串的开头/结尾。默认情况下,只有像grepsedawk这样的工具按行读取。 - Wiktor Stribiżew
这段程序相关的内容翻译为中文:通过符号“^”来确定匹配必须从参数发送的位置开始,对于你的情况,匹配应该从字母“a”或“b”开始。由于原始字符串以字母“a”开头,因此只有在这种情况下才会返回“BOS match”。 - Leonardo
@Leonardo 问题不在于它是单个字符串(它确实是),而在于执行正则表达式匹配时为什么不将字符串中的每一行视为一行。 - JNevill
这个回答解决了你的问题吗?在bash中进行多行正则表达式匹配 - Mike Doe
显示剩余2条评论
1个回答

4

^在POSIX正则表达式(Bash使用POSIX ERE)中匹配整个输入字符串的开头,$匹配整个输入字符串的结尾。您链接的文档提到行,因为大多数文本处理工具(如sedgrepawk)默认按行读取输入,并且在大多数情况下,字符串与行重合。

请参见POSIX regex documentation

9.3.8 BRE Expression Anchoring

BRE可以被限制为仅匹配行的开头或结尾;这称为“定位”。在以下情况下,插入符号和美元符号特殊字符应视为BRE锚点:

  1. 当插入符号('^')作为整个BRE的第一个字符使用时,它将是一个锚点。当插入符号作为子表达式的第一个字符使用时,实现可以将其视为锚点。插入符号将表达式(或可选子表达式)锚定到字符串的开头;仅从字符串的第一个字符开始的序列将被BRE匹配。例如,BRE“^ab”在字符串“abcdef”中匹配“ab”,但在字符串“cdefab”中无法匹配。BRE“(^ab)”可以匹配前者的字符串。便携式BRE应转义子表达式中的前导插入符号以匹配文本中的实际插入符号。

  2. 当美元符号('$')作为整个BRE的最后一个字符使用时,它将是一个锚点。当美元符号作为子表达式的最后一个字符使用时,实现可以将其视为锚点。美元符号将表达式(或可选子表达式)锚定到正在匹配的字符串的结尾;美元符号可以说匹配最后一个字符后面的字符串的结尾。

  3. 通过'^''$'两者都锚定的BRE仅匹配整个字符串。例如,BRE "^abcdef$" 仅匹配由“abcdef”组成的字符串。


还有一个关于ERE表达式定位的章节。 - Benjamin W.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接