正则表达式:指定“空格或字符串开头”和“空格或字符串结尾”
Posted
技术标签:
【中文标题】正则表达式:指定“空格或字符串开头”和“空格或字符串结尾”【英文标题】:Regex: Specify "space or start of string" and "space or end of string" 【发布时间】:2021-07-04 20:33:55 【问题描述】:假设您正在尝试模式匹配“***”。
您想要以下内容:
this is *** and it rocks [MATCH]
*** is the best [MATCH]
i love *** [MATCH]
typo*** rules [NO MATCH]
i love ***typo [NO MATCH]
如果 *** 在两个站点上都有空格,我知道如何解析:
/\s(***)\s/
如果它位于字符串的开头或结尾,则相同:
/^(***)\s/
/\s(***)$/
但是如何使用正则表达式指定“空格或字符串结尾”和“空格或字符串开头”?
【问题讨论】:
【参考方案1】:您可以使用以下任何一种:
\b #A word break and will work for both spaces and end of lines.
(^|\s) #the | means or. () is a capturing group.
/\b(***)\b/
另外,如果您不想在匹配中包含空格,可以使用lookbehind/aheads。
(?<=\s|^) #to look behind the match
(***) #the string you want. () optional
(?=\s|$) #to look ahead.
【讨论】:
\b
是一个零宽度断言;它从不消耗任何字符。无需将其包装在环视中。
请注意,在大多数正则表达式实现中,\b
仅是标准 ASCII,也就是说,不支持 unicode。如果您需要匹配 unicode 单词,您别无选择,只能使用它:***.com/a/6713327/1329367
从匹配中排除组选择的更简单方法是(?:^|\s)
对于 python,将 (?<=\s|^)
替换为 (?:(?<=\s)|(?<=^))
。否则,你会得到error: look-behind requires fixed-width pattern
\b
会考虑其他字符——例如“.
”作为分词符,而提问者特别说的是“空格”。 @gordy 的解决方案似乎更好。【参考方案2】:
(^|\s)
将匹配空格或字符串开头,($|\s)
将匹配空格或字符串结尾。合起来就是:
(^|\s)***($|\s)
【讨论】:
这是唯一适合我的。谢谢@gordy 如果你使用这个模式替换,记得通过替换模式$1string$2
来保留替换结果中的空格。
这也是唯一对我有用的。单词边界似乎从来没有做我想要的。一方面,它们匹配除空格之外的一些字符(如破折号)。这为我解决了这个问题,因为我一直试图将 $
和 ^
放入字符类中,但这表明它们可以放入常规模式组中。
这很好用,但如果您对捕获空间不感兴趣,请使用:(?:^|\s)***(?:$|\s)
【参考方案3】:
这是我会使用的:
(?<!\S)***(?!\S)
换句话说,如果“***”前面没有非空白字符且后面没有非空白字符,则匹配“***”。
这比“空格或锚点”方法更简洁 (IMO),并且它不像 \b
方法那样假设字符串以单词字符开头和结尾。
【讨论】:
很好地解释了为什么要使用它。我会选择这个,但是被测试的字符串总是一行。 @LawrenceDol,你是说(?<=\S)...(?=\S)
吗?请注意,大写的\S
匹配任何不是空格的字符。因此,如果那里有空格字符,或者根本没有字符,则否定的环视将匹配。【参考方案4】:
\b
匹配单词边界(实际上不匹配任何字符),所以下面应该做你想要的:
\b***\b
【讨论】:
对于 Python,将其指定为 raw string 会有所帮助,例如mystr = r'\bstack overflow\b'
以上是关于正则表达式:指定“空格或字符串开头”和“空格或字符串结尾”的主要内容,如果未能解决你的问题,请参考以下文章
求一个匹配 以指定字符开头,指定字符结尾,中间内容任意的正则表达式
求一个匹配 以指定字符开头,指定字符结尾,中间内容任意的正则表达式