正则表达式,但不包括


80

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

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

Answers:


158

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

(?:(?!X).)*

哪里X可以是任何正则表达式。

不过,以您的情况而言,这可能太过分了-在这里,最简单的方法是

[^z]*

这将匹配任何内容z,因此将在下一个之前停止z

因此.*?quick[^z]*将匹配The quick fox jumps over the la

但是,例如,一旦您需要查找多个简单字母,(?:(?!X).)*它就会起作用。

(?:(?!lazy).)*-匹配所有单词,直到单词开头lazy

这是使用先行断言,更具体地说是否定先行。

.*?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将它们包围:只会匹配完整的单词,fox而不会匹配中的狐狸foxy

注意

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

替代解决方案:

在许多情况下,您还可以使用使用惰性量词的更简单,更易读的解决方案。通过添加?*量词,它会尝试匹配从当前位置几个字符尽可能:

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

将匹配任意数量的字符,在字符之前X(可以是任何正则表达式)或字符串的末尾(如果X不匹配)停止。您可能还需要设置“全部点匹配”选项才能起作用。(注意:我在周围添加了一个非捕获组X,以便可靠地将其与轮换隔离)


+1确实不错的答案,很遗憾不适用于grep,但此答案可以。
Alexandre Lavoie

@AlexandreLavoie:有趣。为什么另一个要工作而不是这个要工作?两者都使用先行断言。也许是因为(?:...)没有捕获人员?可以用((?!X).)*吗?
Tim Pietzcker 2013年

1
真的不知道,我既不是正则表达式专家,也不是grep。我过去grep只从sql中的mysql bin transformet过滤对一个数据库的请求。这是野兽:grep -Po "(?s)use database_to_keep(.*?)(?=^use)" mysql-bin.000045.sql > filtered.sql
Alexandre Lavoie

自从我敲击Up键以来,看起来像是一场bash冲突,上一个命令不是我使用的命令:grep -Po "(?s)use database_to_keep(.*?)(?:(?!^use).)*" mysql-bin.000045.sql > filtered.sql
Alexandre Lavoie

1
好的编辑,@ Tim,只需添加$替代方法:替换.*?(?=X).*?(?=X|$)
WiktorStribiżew17年

15

一个前瞻的正则表达式语法,可以帮助你实现你的目标。因此,您的示例的正则表达式是

.*?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

0

试试这个

(.*?quick.*?)z

3
这包括比赛中的“ z”,这正是问询者要避免的事情。也许正则表达式旨在成为“ |”中的术语 替代,并且该替代正则表达式用于执行多个匹配。如果“ z”是一个字符串的开头,而该字符串将与另一个术语匹配,则该匹配将被取消,因为当前的匹配已经消耗了“ z”。
SzczepanHołyszewski2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.