grep regex 向前看或字符串开头(或向后看或字符串结尾)
grep regex lookahead or start of string (or lookbehind or end of string)
我想匹配一个字符串,它可能包含匹配前的某种字符,或者匹配可能从字符串的开头开始(与字符串结尾相同)。
举一个最小的例子,考虑文本 n.b.
,我想在行首和行尾或两个非单词字符之间或某些组合之间进行匹配。最简单的方法是使用单词边界 (\bn\.b\.\b
),但这不匹配;其他包含非单词字符的所需匹配也会发生类似情况。
我目前正在使用 (^|[^\w])n\.b\.([^\w]|$)
,它的效果令人满意,但也会匹配出现在单词前后的非单词字符(如破折号)(如果有)。我在 grep 中执行此操作,因此虽然我可以轻松地将输出传输到 sed,但我使用的是 grep 的 --color
选项,该选项在传输到另一个命令时被禁用(原因很明显)。
编辑:\K
选项(即 (\K^|[^\w])n\.b\.(\K[^\w]|$)
似乎有效,但它也会丢弃输出中匹配项的颜色。虽然我可以再次调用辅助工具,但我如果有一个快速简单的解决方案,我会喜欢的。
编辑:我误解了 \K
运算符;它只是从使用它之前的匹配中删除所有文本。难怪它无法为输出着色。
显然在 lookahead/lookbehinds 中可以匹配字符串的开头;显而易见的解决方案是 (?<=^|[^\w])n\.b\.(?=[^\w]|$)
.
如果您使用 grep,则必须使用 -P
选项,否则环视和 \K
会抛出错误。这意味着您还可以使用 negative 环视。这是您的正则表达式的更简单版本:
(?<!\w)n\.b\.(?!\w)
此外,请注意 (?<=...)
和 (?<!...)
是 lookbehinds,(?=...)
和 (?!...)
是 前瞻。您标题的措辞表明您可能混淆了这些内容,这是初学者常见的错误。
我想匹配一个字符串,它可能包含匹配前的某种字符,或者匹配可能从字符串的开头开始(与字符串结尾相同)。
举一个最小的例子,考虑文本 n.b.
,我想在行首和行尾或两个非单词字符之间或某些组合之间进行匹配。最简单的方法是使用单词边界 (\bn\.b\.\b
),但这不匹配;其他包含非单词字符的所需匹配也会发生类似情况。
我目前正在使用 (^|[^\w])n\.b\.([^\w]|$)
,它的效果令人满意,但也会匹配出现在单词前后的非单词字符(如破折号)(如果有)。我在 grep 中执行此操作,因此虽然我可以轻松地将输出传输到 sed,但我使用的是 grep 的 --color
选项,该选项在传输到另一个命令时被禁用(原因很明显)。
编辑:\K
选项(即 (\K^|[^\w])n\.b\.(\K[^\w]|$)
似乎有效,但它也会丢弃输出中匹配项的颜色。虽然我可以再次调用辅助工具,但我如果有一个快速简单的解决方案,我会喜欢的。
编辑:我误解了 \K
运算符;它只是从使用它之前的匹配中删除所有文本。难怪它无法为输出着色。
显然在 lookahead/lookbehinds 中可以匹配字符串的开头;显而易见的解决方案是 (?<=^|[^\w])n\.b\.(?=[^\w]|$)
.
如果您使用 grep,则必须使用 -P
选项,否则环视和 \K
会抛出错误。这意味着您还可以使用 negative 环视。这是您的正则表达式的更简单版本:
(?<!\w)n\.b\.(?!\w)
此外,请注意 (?<=...)
和 (?<!...)
是 lookbehinds,(?=...)
和 (?!...)
是 前瞻。您标题的措辞表明您可能混淆了这些内容,这是初学者常见的错误。