Regex “如何匹配”;在此字符序列之前的任何内容;在正则表达式中?

Regex “如何匹配”;在此字符序列之前的任何内容;在正则表达式中?,regex,Regex,采用以下正则表达式:/^[^abc]/。这将匹配字符串开头的任何单个字符,a、b或c除外 如果在其后面添加一个*–/^[^abc]*/–正则表达式将继续向结果中添加每个后续字符,直到它遇到a、或b、或c 例如,对于源字符串“qwerty qwerty which abc hello”,表达式将匹配到“qwerty qwerty wh” 但是如果我希望匹配的字符串是“qwerty qwerty whatever” …换言之,如果您希望捕获到“abc”之前的所有内容,我如何将所有内容匹配到(但不包括

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

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

例如,对于源字符串
“qwerty qwerty which abc hello”
,表达式将匹配到
“qwerty qwerty wh”

但是如果我希望匹配的字符串是
“qwerty qwerty whatever”


…换言之,如果您希望捕获到“abc”之前的所有内容,我如何将所有内容匹配到(但不包括)精确的顺序
“abc”

说明:

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

^
匹配行首

*
匹配任何内容,
不贪婪(匹配所需的最小字符数)-[1]

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

whatever whatever something abc something abc

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

$
标记字符串的结尾,因此类似这样的方法应该有效:
[[[^abc]*]$
在这里,您要查找的任何东西都不会在
abc
的任何迭代中结束,但它必须在结尾


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

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

本部分摘自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)]
的操作应该可以做到这一点。

您没有指定要使用哪种风格的正则表达式,但这将 在任何一个最受欢迎的,可以被认为是“完整”的工作

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

当使用
+?
时,不要一次匹配所有项并返回 其他条件(如果有),引擎将通过以下方式匹配下一个字符: 步骤,直到正则表达式的后续部分匹配为止(如果有,请再次执行)。 这是不贪婪的,意味着匹配的可能性最小 满足

/.+X/~“abcXabcXabcX”/.+/~“abcXabcXabcX”
^^^^^^^^^^^^                  ^^^^^^^^^^^^
/.+?X/~“abcXabcXabcX”/.+?/~“abcXabcXabcX”
^^^^                          ^
接下来我们有了
(?=
{contents}
,一个零宽度 断言,环顾四周。此分组结构与其 内容,但不算作匹配的字符(零宽度)。信息技术 仅在匹配与否时返回(断言

因此,在其他术语中,regex
/.+?(?=abc)/
表示:

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


您需要的是像
+?(?=abc)

见:


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

正如@Jared Ng和@Issun所指出的,解决此类正则表达式的关键,如“将所有内容匹配到某个单词或子字符串”或“将所有内容匹配到某个单词或子字符串后”,称为“环视”零长度断言

在您的特定情况下,可以通过积极的前瞻来解决:
+(?=abc)

一幅画抵得上千言万语。请参见屏幕截图中的详细说明

试试这个

.+?efg
查询:

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

hijklmn

对于Java中的regex,我也相信大多数regex引擎,如果您想包括最后一部分,这将起作用:

.+?(abc)
例如,在这一行中:

I have this very nice senabctence
选择“abc”之前的所有字符,并包括abc

使用我们的正则表达式,结果将是:
我有一个非常好的senabc


对此进行测试:

这对正则表达式是有意义的

  • 可以通过以下regex命令获得确切的单词:
  • (“(.*)”)/g

    在这里,我们可以在全局范围内得到属于双引号的确切单词。 例如 如果我们的搜索文本是

    这就是“双引号”单词的例子


    然后我们将从这句话中得到“双引号”。

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

    所以我不得不临时凑合……过了一段时间,我终于找到了我需要的正则表达式:

    正如你们所看到的,我需要在“grp bps”文件夹之前有一个文件夹,但不包括最后一个破折号,而且在“grp bps”文件夹之后至少有一个文件夹

    编辑

    复制粘贴的文本版本(更改文本的“grp bps”):

    .+?(abc)
    
    I have this very nice senabctence
    
    re.findall('.+?(?=abc)', data, re.DOTALL)
    
    .+?(?=(?i)abc)
    
    (?i) - This will make the following abc match case insensitively.