考虑匹配之外的字符的正则表达式

时间:2014-08-26 20:24:46

标签: regex replace sed grep substring

我想知道是否可以创建一个考虑匹配之外字符的正则表达式。因此,例如,正则表达式在语义上意味着“匹配字符'hel',但仅在后跟'lo'时。所以在字符串hello中,它匹配hel

我知道正则表达式的最简单定义只是问“这个字符串是否被接受为匹配”,在这种情况下,这种区别实际上并不意味着什么。但是对于可以突出字符串匹配部分(如grep / egrep)或基于正则表达式替换的引擎(如sed),它既有意义又可以说非常有用。

4 个答案:

答案 0 :(得分:3)

答案是肯定的,通过两种不同的机制。

首先,您可以将lo包含在与整个正则表达式匹配的字符串部分中,但也可以在您关注的hel部分周围设置一个捕获组。这是sed的简单演示,您只需注意找到一个匹配项:

sed -n 's/\(hel\)lo/\1/p' <<<$'hell\nhello\nhelen'

根据您的工具和目标,这可能就是您所需要的。

其次,你可以使用环视 - 在这种情况下,肯定(因为你想确定某些 lookahead (因为你希望它在匹配后)。 grep的GNU实现具有-P标志以启用与Perl5兼容的正则表达式,因此如果您正在使用该版本,则以下命令具有与上述{{1}相同的输出一个:

sed

请注意,OS X的系统grep -oP 'hel(?=lo)' <<<$'hell\nhello\nhelen' 是BSD,而不是GNU。我通过Homebrew安装了GNU版本grep,以便我可以在需要时使用它,但不是在不知不觉中依赖它。

答案 1 :(得分:1)

积极向前看将符合这一要求:

hel(?=lo)

但是sedawk等unix工具不支持环顾四周。

答案 2 :(得分:1)

您需要positive lookahead

hel(?=lo)

以下是演示:http://regexr.com/39d02

如果您需要在命令行上执行此操作,正如其他人提到的那样sedgrep不支持正向前瞻。

以下是使用perl

的示例
echo "hello world, hel world" | perl -ne 's/hel(?=lo)/HEL/g; print;'
# HELlo world, hel world

答案 3 :(得分:0)

您可以使用正则表达式外观。你可以在这里找到非常有趣的文件:

http://www.regular-expressions.info/lookaround.html

  

Lookahead和lookbehind,统称为“lookaround”,是   零长度断言就像行的开始和结束一样,然后开始   和锚点结束。该   区别在于环视实际匹配字符,但随后   放弃匹配,仅返回结果:匹配或不匹配。那   这就是他们被称为“断言”的原因。他们不消耗字符   字符串,但只断言匹配是否可能。   Lookaround允许您创建正则表达式   没有他们就不可能创造,或者会变得非常漫长   没有他们。

正面和负面的前瞻

  

否定前瞻是必不可少的,如果你想匹配的东西不是   其次是别的东西。   否定前瞻提供了解决方案: q(?!u)。否定的   lookahead构造是一对括号,带有开口   括号后跟一个问号和一个感叹号。   在前瞻中,我们有琐碎的正则表达式。

     

积极前瞻的工作原理相同。 q(?= u)匹配q   接下来是你,没有让你成为比赛的一部分。积极的   lookahead构造是一对括号,带有开头   括号后跟一个问号和一个等号。

所以,正如大家回答的那样,你可以使用积极的前瞻:

hel(?=lo)

与您的评论相关,如果您要删除结尾空格,则可以使用此正则表达式:

\s+$

<强> Working demo

enter image description here