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

时间:2011-08-19 16:45:45

标签: regex

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

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

例如,对于源字符串"qwerty qwerty whatever abc hello",表达式将匹配"qwerty qwerty wh"

但如果我希望匹配的字符串为"qwerty qwerty whatever "

,该怎么办?

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

14 个答案:

答案 0 :(得分:794)

你没有指定你正在使用哪种正则表达式,但这会 在任何最受欢迎的工作中都可以被认为是“完整的”。

/.+?(?=abc)/

如何运作

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

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

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

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

然后我们有(?= {contents} )零宽度 断言环顾。这种分组结构与其匹配 内容,但不计入匹配的字符(零宽度)。它 只有在匹配时才返回(断言)。

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

  

匹配任何字符尽可能少,直到找到“abc”,   不计算“abc”。

答案 1 :(得分:95)

如果您希望将所有内容捕获到“abc”:

/^(.*?)abc/

说明:

( )捕获括号内的表达式,以便使用$1$2等进行访问。

^匹配行的开头

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

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

whatever whatever something abc something abc

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

答案 2 :(得分:34)

正如@Jared Ng和@Issun指出的那样,解决这种RegEx的关键是“匹配某个单词或子串的所有内容”或“匹配某个单词或子串之后的所有内容”称为“环视”零长度断言。 Read more about them here.

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

Regex101 Screenshot

答案 3 :(得分:8)

您需要的是查看.+? (?=abc)之类的断言。

请参阅:Lookahead and Lookbehind Zero-Length Assertions

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

答案 4 :(得分:3)

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

.+?(abc)

例如,在这一行:

I have this very nice senabctence

选择所有字符,直到" abc"还包括abc

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

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

答案 5 :(得分:3)

这对正则表达式有意义。

  1. 确切的单词可以从以下正则表达式命令获得:
  2.   

    ("(*)"?)/ G

    在这里,我们可以获得属于双引号内的全局字。 例如, 如果我们的搜索文本是,

    这是"双引号"的例子。字

    然后我们将得到"双引号"从那句话。

答案 6 :(得分:2)

在python上:

'适用于单行情况。

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

[^]+?(?=abc)

答案 7 :(得分:1)

解决方案

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

这将匹配

<块引用>

直到(但不包括)精确序列 "abc"

正如 OP 所要求的那样,即使源字符串包含换行符即使序列以 abc 开头。但是,如果源字符串可能包含换行符,请确保包含多行标志 m

工作原理

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

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

相反

一起 [\s\S] 表示任何字符。这与 . 几乎相同,只是 . 不匹配换行符。

* 表示 0+ 次出现 前面的标记。如果源字符串以 + 开头,我已使用它代替 abc

(?= 被称为正向前瞻。它需要与括号中的字符串匹配,但在它之前停止,因此 (?=abc) 表示“最多但不包括 abc,但 abc 必须存在于源字符串中” .

?[\s\S]* 之间的

(?=abc) 表示懒惰(又名非贪婪)。即停在第一个 abc。没有这个,如果 abc 出现不止一次,它会捕获直到 abc final 出现的每个字符。

答案 8 :(得分:1)

我想将@sidyll 的答案扩展到 不区分大小写 版本的正则表达式。

如果您想匹配 abc/Abc/ABC... 不区分大小写,我需要使用以下正则表达式。

.+?(?=(?i)abc)

说明:

(?i) - This will make the following abc match case insensitively.

正则表达式的所有其他解释与@sidyll 指出的相同。

答案 9 :(得分:0)

我相信你需要子表达式。如果我没记错,你可以使用普通()括号表示子表达式。

这部分来自grep手册:

 Back References and Subexpressions
       The back-reference \n, where n is a single digit, matches the substring
       previously matched  by  the  nth  parenthesized  subexpression  of  the
       regular expression.

^[^(abc)]这样的事情可以做到这一点。

答案 10 :(得分:0)

我在寻求解决问题的帮助后结束了这个stackoverflow问题,但没有找到解决方法:(

所以我不得不即兴创作...一段时间后,我设法达到所需的正则表达式:

enter image description here

如您所见,我需要在“ grp-bps”文件夹之前最多保留一个文件夹,但不包括最后一个破折号。并且必须在“ grp-bps”文件夹之后至少有一个文件夹。

答案 11 :(得分:0)

.*(\s)*?(?=abc)

对于那些也想包含换行符的人。

它将匹配所有内容(包括换行符(无论是否有换行符,即使没有换行符)),直到找到abc

答案 12 :(得分:-1)

$标记字符串的结尾,所以这样的事情应该有效:[[^abc]*]$你在abc的任何迭代中寻找任何不结束的东西,但它会必须在最后

此外,如果您使用带有正则表达式的脚本语言(如php或js),它们会有一个搜索功能,当它第一次遇到模式时会停止(您可以指定从左侧开始或从右侧开始,或者使用php,你可以做一个内爆来镜像字符串)。

答案 13 :(得分:-3)

试试这个

.+?efg

查询:

select REGEXP_REPLACE ('abcdefghijklmn','.+?efg', '') FROM dual;

输出:

hijklmn