【问题标题】:Matching at least one lower case letter AND at least one upper case letter匹配至少一个小写字母和至少一个大写字母
【发布时间】:2016-08-11 13:32:11
【问题描述】:

我正在尝试使用一个约束来提取单词[a-zA-Z]+:一个单词必须包含至少一个小写字母和至少一个大写字母(在单词中的任何位置)。示例:如果输入为hello 123 worLD,则唯一匹配应为worLD

我尝试像这样使用积极的前瞻:

echo "hello 123 worLD" | grep -oP "(?=.*[a-z])(?=.*[A-Z])[a-zA-Z]+"
hello

这是不正确的:唯一的匹配是hello 而不是worLD。然后我尝试了这个:

echo "hello 123 worLD" | grep -oP "\K((?=.*[a-z])(?=.*[A-Z])[a-zA-Z]+)"
hello
worLD

这仍然不正确:hello 不应匹配。

【问题讨论】:

    标签: regex grep regex-lookarounds


    【解决方案1】:

    前瞻中的.* 不仅会检查相邻单词中是否存在字母,还会检查字符串后面的字母。使用[a-zA-Z]*:

    echo "hello 123 worLD" | grep -oP "\\b(?=[A-Za-z]*[a-z])(?=[A-Za-z]*[A-Z])[a-zA-Z]+"
    

    demo online

    我还在开头添加了一个字边界\b,这样前瞻检查只在一个字边界之后执行。

    【讨论】:

      【解决方案2】:

      答案:

      echo "hello 123 worLD" | grep -oP "\b(?=[A-Z]+[a-z]|[a-z]+[A-Z])[a-zA-Z]*"
      

      演示:https://ideone.com/HjLH5o

      说明:

      首先检查单词是否以一个或多个大写字母开头,后跟一个小写字母,反之亦然,后跟任意数量的小写和大写字母。

      性能:

      This solution 需要 31 步才能在提供的测试字符串上找到匹配项,而 accepted solution 需要 47 步。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-26
        • 2019-11-09
        • 1970-01-01
        • 2016-12-14
        • 2020-12-06
        • 2013-05-27
        • 2017-03-13
        • 2016-01-23
        相关资源
        最近更新 更多