如何在正则表达式中匹配"直到这个字符序列"的任何内容?

cal*_*lum 454 regex

拿这个正则表达式:/^[^abc]/.这将匹配字符串开头的任何单个字符,a,b或c除外.

如果你*在它之后添加- /^[^abc]*/- 正则表达式将继续将每个后续字符添加到结果中,直到它遇到a a, b, c.

例如,使用源字符串"qwerty qwerty whatever abc hello",表达式将匹配"qwerty qwerty wh".

但是如果我想要匹配的字符串呢? "qwerty qwerty whatever "

...换句话说,我怎样才能匹配到(但不包括)确切序列的所有内容 "abc"

sid*_*yll 915

您没有指定您正在使用哪种正则表达式,但这适用于任何可被视为"完整"的最流行的正则表达式.

/.+?(?=abc)/
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

.+? 部分是.+ (一个或多个任何东西)的非贪婪版本 .当我们使用时.+,引擎将基本匹配所有内容.然后,如果正则表达式中还有其他内容,它将返回尝试匹配以下部分的步骤.这是 贪婪的行为,意味着尽可能地满足.

使用时 .+?,引擎将不是一次匹配并返回其他条件(如果有的话),引擎将逐步匹配下一个字符,直到匹配正则表达式的后续部分(如果有的话).这是不贪婪的,意味着 尽可能少地满足.

/.+X/  ~ "abcXabcXabcX"        /.+/  ~ "abcXabcXabcX"
          ^^^^^^^^^^^^                  ^^^^^^^^^^^^

/.+?X/ ~ "abcXabcXabcX"        /.+?/ ~ "abcXabcXabcX"
          ^^^^                          ^
Run Code Online (Sandbox Code Playgroud)

接下来我们有 一个 零宽度断言, 环顾四周.此分组构造与其内容匹配,但不计为匹配的字符(零宽度).只有在匹配与否时才会返回(断言).(?={contents})

因此,在其他方面,正则表达式/.+?(?=abc)/意味着:

匹配任何字符尽可能少,直到找到"abc",而不计算"abc".

  • 杰出的代码功能描述. (42认同)
  • 如果应该捕获它们,这可能不适用于换行符. (11认同)
  • @ robbie0630` +`表示1或更多,其中`*`表示0或更多.包含/排除`?`会使它变得贪婪或不贪婪. (4认同)
  • `.+?`和`.*`之间有什么区别? (3认同)
  • @ testerjoe2 /.+?(?=abc|xyz)/ (2认同)
  • 这在多行中不起作用。问题要求“任何事情” (2认同)
  • @einord 如果需要使用换行符,您可以将 /s 标志添加到正则表达式中。 (2认同)
  • 我注意到,如果您要查找的模式不存在,这将无法选择任何内容,相反,如果您使用`^(?:( ?! abc)(?! def)。)*`,您可以链接以排除不包含的模式不需要,即使该模式不存在,它仍会根据需要获取所有内容 (2认同)
  • 这不适用于 Google Apps 脚本正则表达式,“s”标志在那里不起作用。因此,您需要使用 [\\S\\s] 作为解决方法包罗万象(确保它是双重转义的) (2认同)

Jar*_* Ng 109

如果你想捕捉到"abc"的所有内容:

/^(.*?)abc/
Run Code Online (Sandbox Code Playgroud)

说明:

( )使用捕获的括号内的访问的表达$1,$2等等.

^ 匹配线的开始

.*匹配任何东西,?非贪婪(匹配所需的最小字符数) - [1]

[1]需要这样做的原因是,否则,在以下字符串中:

whatever whatever something abc something abc
Run Code Online (Sandbox Code Playgroud)

默认情况下,正则表达式是贪婪的,这意味着它将尽可能匹配.因此/^.*abc/会匹配"无论什么东西abc某事".添加非贪婪量词?使正则表达式只匹配"无论什么东西".

  • 这是**每个**正则表达式应答***应该***看看 - 所有部分的例子和**解释**... (3认同)
  • 谢谢,但你的**在比赛中包含了abc.换句话说,产生的匹配是"无论什么东西abc". (2认同)
  • 你能解释一下你最终想要做什么吗?如果您的场景是: (A) 您想要获取“abc”之前的所有内容 - 只需在您想要捕获的内容周围使用括号即可。(B) 您想要将字符串与“abc”匹配——无论如何您都必须检查 abc,因此无论如何它都必须是正则表达式的一部分。您还能如何检查它是否存在? (2认同)

Dev*_*evy 40

正如@Jared Ng和@Issun指出的那样,解决这种RegEx的关键是"匹配某个单词或子串的所有内容"或"匹配某个单词或子串后的所有内容"称为"环视"零长度断言.在这里阅读更多相关信息.

在您的特定情况下,可以通过积极展望来解决.一张图片胜过千言万语.请参阅屏幕截图中的详细说明.

Regex101截图

  • `。+?(?= abc)`复制可粘贴的正则表达式值得更多。 (9认同)

Pau*_*one 32

解决方案

/[\s\S]*?(?=abc)/

这将匹配

一切直到(但不包括)确切的顺序"abc"

正如OP所要求的,即使源字符串包含换行符即使序列以abc. m但是,如果源字符串可能包含换行符,请务必包含多行标志。

怎么运行的

\s表示任何空白字符(例如空格、制表符、换行符)

\S表示任何非空白字符;即相反\s

在一起[\s\S]意味着任何字符.这几乎与除了.不匹配换行符之外相同。

*表示前面的标记出现 0 次以上。我已经使用它来代替+源字符串以abc.

(?=称为正向前瞻。它需要与括号中的字符串匹配,但在其之前停止,因此(?=abc)意味着“直到但不包括abc,但abc必须出现在源字符串中”。

?之间[\s\S]*(?=abc)意味着懒惰(又名非贪婪)。即停在第一个abc。如果没有这个,它会捕获每个字符,直到最后出现的abcifabc出现多次。


Bla*_*ire 9

匹配从开始到“ABC”或“行结束”之前(如果没有 ABC)

(1) 如果字符串中任何地方都不包含 ABC,则匹配整个字符串

(2) 不匹配空字符串

(不检查带换行符的字符串)

^.+?(?=ABC|$)
Run Code Online (Sandbox Code Playgroud)


aev*_*nko 8

你需要的是看看断言.+? (?=abc).

请参阅:Lookahead和Lookbehind Zero-Length Assertions

请注意,这[abc]不一样abc.在括号内,它不是一个字符串 - 每个字符只是其中一种可能性.在括号外面它变成了字符串.


Dad*_*dan 7

对于 Java 中的正则表达式,我也相信在大多数正则表达式引擎中,如果您想包含最后一部分,这将起作用:

.+?(abc)
Run Code Online (Sandbox Code Playgroud)

例如,在这一行中:

I have this very nice senabctence
Run Code Online (Sandbox Code Playgroud)

选择“abc”之前的所有字符并包括 abc

使用我们的正则表达式,结果将是: I have this very nice senabc

测试一下:https : //regex101.com/r/mX51ru/1


Dav*_*der 7

在Python中:

.+?(?=abc)适用于单行情况。

[^]+?(?=abc)不起作用,因为 python 无法将 [^] 识别为有效的正则表达式。要使多行匹配工作,您需要使用 re.DOTALL 选项,例如:

re.findall('.+?(?=abc)', data, re.DOTALL)
Run Code Online (Sandbox Code Playgroud)


Loa*_*ron 5

所以我不得不即兴发挥......一段时间后我设法达到了我需要的正则表达式:

在此输入图像描述

正如您所看到的,我需要在“grp-bps”文件夹之前最多有一个文件夹,不包括最后一个破折号。并且要求“grp-bps”文件夹之后至少有一个文件夹。

用于复制粘贴的文本版本(将“grp-bps”更改为您的文本):

.*\/grp-bps\/[^\/]+
Run Code Online (Sandbox Code Playgroud)

在寻求帮助来解决我的问题后,我结束了这个堆栈溢出问题,但我没有找到任何解决方案:(

  • 没有文字版吗? (9认同)