首页 文章

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

提问于
浏览 1525
354

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

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

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

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

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

10 回答

  • 695

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

    .+?(abc)
    

    例如,在这一行:

    I have this very nice senabctence
    

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

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

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

  • 83

    试试这个

    .+?efg
    

    查询:

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

    输出:

    hijklmn
    
  • 30

    你没有指定你正在使用哪种正则表达式,但这适用于任何可以被认为是“完整”的最流行的正则表达式 .

    /.+?(?=abc)/
    

    它是如何工作的

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

    当使用 .+? 时,不是一次匹配all而是返回其他条件(如果有的话),引擎将逐步匹配下一个字符,直到匹配正则表达式的后续部分(如果有的话) . 这是 un-greedy ,意思是匹配 the fewest possible to satisfy .

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

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

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

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

  • 8

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

    见:Lookahead and Lookbehind Zero-Length Assertions

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

  • 3

    $ 标记了一个字符串的结尾,所以这样的东西应该可以工作: [[^abc]*]$ 你在 abc 的任何迭代中寻找任何不结束的东西,但它必须在最后

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

  • 1

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

    /^(.*?)abc/
    

    说明:

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

    ^ 匹配行的开头

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

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

    whatever whatever something abc something abc
    

    默认情况下,正则表达式是贪婪的,这意味着它将尽可能匹配 . 因此 /^.*abc/ 将匹配"whatever whatever something abc something " . 添加非贪心量词 ? 使正则表达式只匹配"whatever whatever something " .

  • 0

    这对正则表达式有意义 .

    • 确切的单词可以从以下regex命令中获取:

    (“( . *?)”)/ g

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

    这是“双引号”单词的示例

    那么我们将从那句话中得到“双引号” .

  • 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)] 这样的东西应该可以做到 .

  • -1

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

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

    enter image description here

    如您所见,我需要在“grp-bps”文件夹之前最多一个文件夹,而不包括最后一个短划线 . 并且需要在“grp-bps”文件夹后至少有一个文件夹 .

  • -3

    正如@Jared Ng和@Issun指出的那样,解决像"matching everything up to a certain word or substring"或"matching everything after a certain word or substring"这样的RegEx的关键是"lookaround"零长度断言 . Read more about them here.

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

    Regex101 Screenshot

相关问题