匹配除特定单词之外的所有字符

时间:2014-07-14 21:24:57

标签: python regex

在过去的几天里,我一直在学习Regex(在python中实现它),并且没有想出如何解决这个问题。

我有这种格式的文字:

FOO1 = BAR2 AND Var1
Gene3 = Gene4 >= 3
Kinase = MATH OR NOT Science
BOOP = 3

我想识别每个变量名称(例如FOO1,BAR2,BOOP)并忽略任何逻辑运算符(例如AND,OR,NOT)

以下是我尝试解决方案:(?!AND)(?!OR)(?!NOT)([a-zA-Z0-9]+)

我很难告诉后台人员识别AND,OR,而不是单词而不是单个字符。

任何帮助将不胜感激。提前谢谢!

2 个答案:

答案 0 :(得分:2)

首先,感谢您展示您的尝试。其次,让我们尝试以几种方式改进你的正则表达式:

  1. 您已经有了一些很好的前瞻,可以简化为:(?!AND|OR|NOT)([a-zA-Z0-9]+)

  2. 我们并不真正需要一个捕获小组(?!AND|OR|NOT)[a-zA-Z0-9]+

  3. 我们添加一个wordboundary以阻止部分匹配(?!AND|OR|NOT)\b[a-zA-Z0-9]+

  4. 让我们举个例子foo AND bar作为输入:

       
    foo AND bar
    ^ Checks if there is no "AND", "OR" or "NOT" literally
    since there isn't, it will match foo with [a-zA-Z0-9]+
    
    foo AND bar
       ^ no match
    
    foo AND bar
        ^ Here it will fail because of the negative lookahead
    
    foo AND bar
         ^ It will succeed because there is no "AND", "OR" or "NOT" literally
    

    因此解决方案是添加wordboundary \b,这与(?<!\w)相同。这意味着如果后面有一个单词字符,正则表达式将会失败。

    foo AND bar
         ^ fail, because there is a word character behind
    
    foo AND bar
            ^^^ match
    

    Online demo

答案 1 :(得分:1)

您需要使用单词边界(\b)。这对于查找单词的开头或结尾非常有用。它通过在^上进行零长度断言(因此它实际上不匹配任何东西,类似于锚点$(^\w|\w\W|\W\w|\w$))来工作。换句话说,确保在非单词字符或字符串的开头/结尾旁边有一个单词(\w === [a-zA-Z0-9_])。您也可以组合表达式(并且捕获组很可能是不必要的):

\b(?!AND|OR|NOT)[a-zA-Z0-9]+

Demo

请注意,在表达式的末尾不需要单词边界,因为正则表达式是贪婪的并且会尽可能多地抓取[a-zA-Z0-9]+


如果您的变量中可以包含下划线(_),则使用\w速记字符类(上面提到的与[a-zA-Z0-9_]相同)可能更清晰。最后的表达是:

\b(?!AND|OR|NOT)\w+

旁注:(?!...)是一个负面的提前而不是之后(他们确保引擎前面的字符是内部指针不匹配...)。