【问题标题】:using regex to find substring使用正则表达式查找子字符串
【发布时间】:2019-10-25 00:33:10
【问题描述】:

我在使用正则表达式时遇到问题。我正在使用以下正则表达式:

\\S*the[^o\\s]*(?<!theo)\\b

我使用的句子是:

如果全世界都说 theo 不是奥利奥饼干,那么 thetatheoder theotatheder thetatheder 是非常棒的。

我想要的输出是有模式:thetatheder, extratheaterly?

简而言之,我可以将 'the(The)' 作为一个完整字符串或不包含 'theo' 的字符串中的子字符串。

如何修改我的正则表达式来实现这一点?我在想的是申请,管道操作还是问号。但它们似乎都不可行。

【问题讨论】:

  • 您使用什么语言?你不能同时使用 Java 和 python。
  • 我正在使用 python

标签: python regex machine-learning nlp artificial-intelligence


【解决方案1】:

您可以使用\S 作为开始边界和否定前瞻来确保单词不包含theo。

要匹配 The 或 the 你可以使模式不区分大小写。

(?<!\S)(?!\S*theo\S*)\S*the\S*

部分

  • (?&lt;!\S) 否定后视,断言左边的不是非 whitspace 字符
  • (?!\S*theo\S*)负前瞻,断言右边不包含theo
  • \S*the\S* 匹配 the 被匹配 0+ 次非空白字符包围

Regex demo

如果你只使用单词字符,你也可以使用单词边界\b

\b(?!\w*theo\w*)\w*the\w*\b

Regex demo

或者你可以断言单词的一部分是the,并使用断言匹配它,如果你匹配一个t,它后面不应该跟着heo

\b(?=\S*the\S*)[^t\s]*(?:t(?!heo)[^t\s]*)+\b

Regex demo

【讨论】:

    【解决方案2】:

    通用

    如果你想设计一个通用的表达式,也许你可以从一些类似的表达式开始,

    \S*the[^o\s]*\b
    

    我猜这取决于你想要匹配和不匹配的内容。

    Demo

    非通用

    我猜你可以简单地找到有助于解决你的问题的单词边界 (\b),用一些类似于,

    \b[Tt]he\b|\b[Tt]hen\b|\bextratheaterly\b
    

    Demo 1

    或者,

    \b(?:[Tt]hen?|[Ee]xtratheaterly)\b
    

    Demo 2

    Java 测试

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    
    public class RegularExpression{
    
        public static void main(String[] args){
    
            final String regex = "\\b(?:[Tt]hen?|[Ee]xtratheaterly)\\b";
            final String string = "If the world says that theo is not oreo cookies then thetatheoder is extratheaterly good.\n\n"
                 + "If The world says that theo is not oreo cookies Then thetatheoder is Extratheaterly good.\n\n"
                 + "If notthe world says that theo is not oreo cookies notthen thetatheoder is notextratheaterly good.\n\n\n";
    
            final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
            final Matcher matcher = pattern.matcher(string);
    
            while (matcher.find()) {
                System.out.println("Full match: " + matcher.group(0));
                for (int i = 1; i <= matcher.groupCount(); i++) {
                    System.out.println("Group " + i + ": " + matcher.group(i));
                }
            }
    
    
        }
    }
    

    输出

    Full match: the
    Full match: then
    Full match: extratheaterly
    Full match: The
    Full match: Then
    Full match: Extratheaterly
    

    Python 测试

    import re
    string = '''
    If the world says that theo is not oreo cookies then thetatheoder is extratheaterly good.
    
    If The world says that theo is not oreo cookies Then thetatheoder is Extratheaterly good.
    
    If notthe world says that theo is not oreo cookies notthen thetatheoder is notextratheaterly good.
    '''
    
    expression = r'\b(?:[Tt]hen?|[Ee]xtratheaterly)\b'
    
    print(re.findall(expression, string))
    print([m.group(0) for m in re.finditer(expression, string)])
    

    输出

    ['the', 'then', 'extratheaterly', 'The', 'Then', 'Extratheaterly']
    ['the', 'then', 'extratheaterly', 'The', 'Then', 'Extratheaterly']
    

    如果您希望简化/修改/探索表达式,在regex101.com 的右上角面板中已对此进行了说明。如果您愿意,您还可以在 this link 中观看它如何与一些示例输入匹配。


    正则表达式电路

    jex.im 可视化正则表达式:

    【讨论】:

    • 你好艾玛,我想要一个通用的表达方式。该示例只是一个示例。
    • 它选择应该跳过的文本:theothatherd。
    【解决方案3】:
    \b[A-Za-z]*he([a-z](?<!theo))*\b
    

    匹配,然后,在剧院外

    \b 字边界

    [A-Za-z] 匹配任何字母

    [a-z] 匹配任何小写字母

    * 匹配 0 个或多个

    ([a-z](?<!theo))*
    

    这是棘手的部分。 它说任何字母,确保在添加该字母后不拼写theo(向后看)

    看看消极的lookbehind和消极的lookaheads。

    【讨论】:

    • 如果我有这样的句子: The then theotatheder thetatheo 然后,这里将匹配 'The'、'then' 和 'theotatheder'。它也应该跳过最后一个。
    • 发生的事情是 [A-Za-z]* 一开始就匹配 theo。需要修改为。 \b([A-Za-z](?
    • 是的,我在表达式的第一部分使用了 (?!theo) 来向后看并在模式中环顾四周但是,它不起作用。
    猜你喜欢
    • 2012-12-01
    • 1970-01-01
    • 2016-05-16
    • 2012-05-12
    • 2014-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多