“搜索到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 将仅匹配完整的单词 fox 而不是 foxy 中的狐狸。
注意
如果要匹配的文本也可以包含换行符,则需要设置正则表达式引擎的“点匹配所有”选项。通常,您可以通过在正则表达式前面加上 (?s) 来实现,但这并不适用于所有正则表达式引擎(尤其是 JavaScript)。
替代解决方案:
在许多情况下,您还可以使用使用惰性量词的更简单、更易读的解决方案。通过将? 添加到* 量词,它将尝试从当前位置匹配尽可能少的字符:
.*?(?=(?:X)|$)
将匹配任意数量的字符,在X(可以是任何正则表达式)或字符串结尾(如果X 不匹配)之前停止。您可能还需要设置“点匹配所有”选项才能使其正常工作。 (注意:我在X 周围添加了一个非捕获组,以便可靠地将其与交替隔离)