带有一个运算符或另一个运算符的Python正则表达式,但不能同时使用

时间:2018-10-13 19:04:04

标签: python regex

我想使用正则表达式来匹配小写字母,后跟一个+和一个数字或一个-和一个数字,或两者都匹配,但不能是同一运算符的2倍。 / p>

要清楚,这些都是可以接受的

a
a+1
a-2
a+3-4
a-5+6 

虽然这些是不可接受的

a+1+2
a-3-4

我当前的表情是

r = re.compile(r"[a-z]{1}([+-]\d){0,2}?$")

允许两个都不可接受的字符串。如何指定如果已经使用了一个运算符,它就不会出现两次?

4 个答案:

答案 0 :(得分:4)

您可以在否定前瞻中使用向后引用(尽管整个正则表达式必须有所更改):

[a-z](?:([+-])\d(?:(?!\1)[+-]\d)?)?$

regex101 demo

我代替了([+-]\d){0,2}?,做了两次这样的重复:([+-])\d(?:(?!\1)[+-]\d)?,第一次出现的运算符和数字是([+-])\d,第二次出现了(?:(?!\1)[+-]\d)?。 / p>

在第一次出现时,正则表达式存储匹配的值(+-),在第二次中,确保此匹配的值不匹配(?!\1)[+-](?! ... )是否定前瞻的语法,因此[+-]不能与此否定前瞻匹配)

答案 1 :(得分:2)

您可以将它们分为两种情况:

r = re.compile(r'^[a-z]([+]\d([-]\d)?|[-]\d([+]\d)?)?$')

regex101

所以我们基本上在这里有两个分支:

  1. [+]\d([-]\d)?:我们以+,一个数字以及一个可选的-和一个数字开头;和
  2. [-]\d([+]\d)?:我们以-,一个数字以及一个可选的+和一个数字开头。

然后我们在两者之间建立一个联合,并将其设为可选。

答案 2 :(得分:2)

尝试一下:

[a-z](?!(\+\d\+\d)|(\-\d\-\d))((\+|\-)\d)*

详细版本(最好使用它):

[a-z]                     # find this
(?!                       # not followed by:
  (\+\d\+\d) | (\-\d\-\d) #                  (this or that)
)
(
  (\+|\-)\d               # followed by this
)*                        # 0 or more times

答案 3 :(得分:0)

尝试这个:

(?!(.+?\+){2,}|(.*?\-){2,})[a-z][\d+-]*

Demo at regex 101

说明:

  • (?!(.+?\+){2,}|(.*?\-){2,})否定前瞻断言+-

  • 的出现不超过两次
  • [a-z]匹配小写字母

  • [\d+-]*匹配零个或多个数字,+-