【问题标题】:How to match the first word after an expression with regex?如何用正则表达式匹配表达式后的第一个单词?
【发布时间】:2010-10-07 11:15:30
【问题描述】:

例如,在此文本中:

Lorem ipsum dolor sit amet,consectetur adipiscing elit。 Nunc eu Tellus vel nunc pretium lacinia。 Proin sed lorem。疯狂的 ipsum。 Nunc a libero quis risus sollicitudin imperdiet。

我想匹配 'ipsum' 之后的单词。

【问题讨论】:

    标签: regex lookbehind word-boundary


    【解决方案1】:

    这听起来像是一项寻找后向的工作,但您应该知道并非所有的正则表达式都支持它们。在您的示例中:

    (?<=\bipsum\s)(\w+)
    

    这将匹配任何跟在“ipsum”后面的字母字符作为一个完整的单词,后面跟一个空格。它确实 匹配“ipsum”本身,您无需担心在以下情况下重新插入它,例如替换。

    不过,正如我所说,某些风格(例如 JavaScript)根本不支持后向查看。许多其他人(实际上大多数人)只支持“固定宽度”的lookbehinds——所以你可以使用这个例子,但不能使用任何重复运算符。 (换句话说,(?&lt;=\b\w+\s+)(\w+) 不会工作。)

    【讨论】:

    • 不过,在使用通配符时,Lookbehinds 往往非常有限。
    • 这里甚至可能不需要 Lookbehinds。根据问题中“我想匹配”所指的内容,请参阅 David Kemp 的解决方案。
    • 零宽度往往是你想要的,只是分组是一个微不足道的出狱卡。
    • 固定宽度是一个误导性术语——它更像是“最大宽度”,是吗?在大多数情况下,可以使用合适的限制,例如:(?
    • @Peter — 不,它确实是 固定 宽度。在 Python 中尝试你的正则表达式;它会引发异常。
    【解决方案2】:

    其他一些响应者建议使用不依赖于lookbehinds 的正则表达式,但我认为需要一个完整的工作示例来理解这一点。这个想法是您以正常方式匹配整个序列(“ipsum”加上下一个单词),然后使用捕获组来隔离您感兴趣的部分。例如:

    String s = "Lorem ipsum dolor sit amet, consectetur " +
        "adipiscing elit. Nunc eu tellus vel nunc pretium " +
        "lacinia. Proin sed lorem. Cras sed ipsum. Nunc " +
        "a libero quis risus sollicitudin imperdiet.";
    
    Pattern p = Pattern.compile("ipsum\\W+(\\w+)");
    Matcher m = p.matcher(s);
    while (m.find())
    {
      System.out.println(m.group(1));
    }
    

    请注意,这会同时打印“dolor”和“Nunc”。要使用lookbehind 版本做到这一点,您必须做一些骇人听闻的事情,例如:

    Pattern p = Pattern.compile("(?<=ipsum\\W{1,2})(\\w+)");
    

    那是在 Java 中,它要求后向有一个明显的最大长度。有些版本甚至没有那么大的灵活性,当然,有些版本根本不支持lookbehinds。

    但是,人们在他们的示例中遇到的最大问题似乎不是lookbehinds,而是单词边界。 David Kemp 和 ck 似乎都希望 \b 匹配“m”后面的空格字符,但事实并非如此;它匹配“m”和空格之间的位置(或边界)

    这是一个常见的错误,我什至在几本书和教程中都看到过这个错误,但是单词边界构造 \b 永远不会匹配任何字符。这是一个零宽度断言,如环视和锚点(^$\z 等),它匹配的位置是前面有一个单词字符但后面没有一个,或者后跟一个单词字符,前面没有一个。

    【讨论】:

      【解决方案3】:

      ipsum\b(\w*)

      【讨论】:

      • 这似乎只匹配 ipsum。
      • 我可能至少会这样做 \b+(\w+)
      • ipsum\b+(\w+) 不是有效的正则表达式。
      • @Matthew Taylor:这取决于您的平台。您没有指定您使用的平台/语言。
      • \b+ 匹配一个或多个单词边界,这是没有意义的,因为单词边界的长度为零。有些风格会忽略 + 但其他风格会拒绝它作为错误。我认为“ipsum\s+(\w+)”是你正在摸索的。
      【解决方案4】:

      使用javascript,您可以使用(?=ipsum.*?(\w+))

      这也将获得第二次出现(Nunc)

      【讨论】:

        【解决方案5】:
        (?<=\bipsum\s|\bipsum\.\s)(\w+)
        

        /(?&lt;=\bipsum\s|\bipsum\.\s)(\w+)/gm 正面观察 (?&lt;=\bipsum\s|\bipsum\.\s) 断言下面的正则表达式匹配

        1. 第一选择 \bipsum\s \b 在单词边界处断言位置:(^\w|\w$|\W\w|\w\W) ipsum 匹配字符 ipsum 字面意思(区分大小写) \s 匹配任何空白字符(等于[\r\n\t\f\v ]
        2. 第二选择 \bipsum\.\s \b 在单词边界处断言位置:(^\w|\w$|\W\w|\w\W) ipsum 匹配字符 ipsum 字面意思(区分大小写) .匹配字符。字面意思(区分大小写) \s 匹配任何空白字符(等于[\r\n\t\f\v ]) 第一捕获组 (\w+) \w+ 匹配任何单词字符(等于[a-zA-Z0-9_]
        • 量词 - 匹配一次到无限次,尽可能多次,根据需要回馈(贪婪) 全局模式标志 g 修饰符:全局。所有比赛(第一场比赛后不返回) m 修饰符:多行。使 ^ 和 $ 匹配每行的开始/结束(不仅是字符串的开始/结束)

        【讨论】:

          【解决方案6】:

          示例语句:“availebleLimit: Double?”。 İ如果你想在':'字符之后找到单词,可以使用下面的正则表达式

          正则表达式 => :.+$

          【讨论】:

            【解决方案7】:

            ipsum\b(.*)\b

            编辑: 尽管取决于您的正则表达式实现,这可能会很饿并在 ipsum 之后找到所有单词

            【讨论】:

            • 这将匹配句子的其余部分。
            • 你必须让它变得不贪心
            • 实际上它不依赖于实现,或者至少我从未遇到过默认情况下非贪婪的正则表达式实现。非贪婪总是一个开关(至少在 Perl、PHP、Java 和 .Net 中)。
            • @cletus:根据定义,正则表达式实现可以包括将开关传递给对正则表达式函数的调用
            • 即使你让它不贪婪——即,“ipsum\b(.*?)\b”——它仍然不起作用。 "(.*?)" 只会匹配 'ipsum' 和下一个单词之间的空格。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多