2010-10-03 59 views
38

对于正则表达式,搜索直到但不包括的语法是什么?有点像:正则表达式直到但不包括

Haystack: 
The quick red fox jumped over the lazy brown dog 

Expression: 
.*?quick -> and then everything until it hits the letter "z" but do not include z 

回答

104

说的明确的方式 “搜索,直到X但不包括X” 是:

(?:(?!X).)* 

其中X可以是任何正则表达式。

在你的情况,不过,这可能是矫枉过正 - 这里最简单的方法是

[^z]* 

这将只是z匹配任何内容,因此接下来的z之前就停。因此.*?quick[^z]*将匹配The quick fox jumps over the la

但是,只要你有一个以上的简单的字母看出来的,(?:(?!X).)*进场,例如

(?:(?!lazy).)* - 匹配任何东西,直到字lazy的开始。

这是使用一个lookahead assertion,更具体地说是一个负面的前瞻。

.*?quick(?:(?!lazy).)*将匹配The quick fox jumps over the

说明:

(?:  # Match the following but do not capture it: 
(?!lazy) # (first assert that it's not possible to match "lazy" here 
.   # then match any character 
)*   # end of group, zero or more repetitions. 

此外,对于关键字搜索时,你可能想围绕他们与单词边界锚:\bfox\b将只匹配在foxy的整个字fox但不是狐狸。

注意

如果要匹配的文本也可以包括换行符,你将需要设置“点匹配所有”的正则表达式引擎的选项。通常,您可以通过将(?s)添加到正则表达式来实现该功能,但不适用于所有正则表达式引擎(特别是JavaScript)。

替代解决方案:

在很多情况下,你也可以使用使用惰性限定符更简单,更可读的解决方案。通过添加?*量词,它会尝试尽可能少的字符可能从当前位置匹配:

.*?(?=(?:X)|$) 

将匹配任何数目的字符,停权之前X(可以是任何正则表达式)或字符串的结尾(如果X不匹配)。您可能还需要设置“点匹配全部”选项才能使其工作。(注:我为了可靠地交替隔离它添加非捕获组围绕X

+0

+1真的很好的答案,不幸的是不带'grep'工作,但这【答案】(http://stackoverflow.com/a/5979402/ 354831)呢。 – 2013-06-10 02:58:46

+0

@AlexandreLavoie:有趣。为什么另一个工作,而不是这个?两者都使用前瞻断言。也许这只是因为'(?:...)'非捕获组?它是否和'((?!X)一起工作。)*'? – 2013-06-10 07:40:12

+1

真的不知道,我不是正则表达式专家,也不是grep。我正在使用'grep'在sql中过滤来自mysql bin transformet的只有一个数据库的请求。这里是兽:'grep的-Po的mysql-bin.000045.sql> filtered.sql' – 2013-06-10 07:49:23

0

试试这个

(.*?quick.*?)z 
+0

这包括在比赛中, “Z”,这正是提问者想要避免的。正则表达式可能是'|'中的术语替代方案,并且该替代正则表达式用于执行多个匹配。如果“z”是一个字符串的开始,该字符串可以通过备选中的**另一个**项匹配,则该匹配将被没收,因为当前匹配已经消耗了“z”。 – 2015-08-27 11:24:06

5

一个lookahead regex syntax可以帮你实现你的目标。因此,对于你的例子正则表达式是

.*?quick.*?(?=z) 

而且要注意的(?=z)先行前.*?懒匹配是很重要的:表达一个子串匹配,直到第一发生z信。

下面是C#代码示例:

const string text = "The quick red fox jumped over the lazy brown dogz"; 

string lazy = new Regex(".*?quick.*?(?=z)").Match(text).Value; 
Console.WriteLine(lazy); // The quick red fox jumped over the la 

string greedy = new Regex(".*?quick.*(?=z)").Match(text).Value; 
Console.WriteLine(greedy); // The quick red fox jumped over the lazy brown dog