限制正则​​表达式长度

时间:2017-06-25 09:03:56

标签: python regex

我在python中遇到一个问题,创建一个正则表达式来获取与正则表达式匹配的每个出现。 我有这个代码,我需要帮助。

strToSearch= "1A851B 1C331 1A3X1 1N111 1A3 and a whole lot of random other words."
print(re.findall('\d{1}[A-Z]{1}\d{3}', strToSearch.upper())) #1C331, 1N111
print(re.findall('\d{1}[A-Z]{1}\d{1}[X]\d{1}', strToSearch.upper())) #1A3X1
print(re.findall('\d{1}[A-Z]{1}\d{3}[A-Z]{1}', strToSearch.upper())) #1A851B
print(re.findall('\d{1}[A-Z]{1}\d{1}', strToSearch.upper())) #1A3

>['1A851', '1C331', '1N111']
>['1A3X1']
>['1A851B']
>['1A8', '1C3', '1A3', '1N1', '1A3']

正如你所看到的,它在第一个中返回“1A851”,我不希望它。如何防止它出现在第一个正则表达式?有些事情你可以知道它可能出现在字符串中,如“单词1A851B?”所以我需要保持标点不被抓住。

另外,我如何将这些组合成一个正则表达式。基本上我的最终目标是在python中运行if语句,类似于下面的伪代码。

lstResults = []
strToSearch= " Alot of 1N1X1 people like to eat 3C191 cheese and I'm a 1A831B aka 1A8."
lstResults = re.findall('<REGEX HERE>', strToSearch)
for r in lstResults:
    print(r)

所需的输出将是

1N1X1
3C191 
1A831B
1A8

3 个答案:

答案 0 :(得分:0)

Yo可能会使用单词边界:

\b\d{1}[A-Z]{1}\d{3}\b

请参阅demo

对于组合,根据您考虑单词“随机单词”的标准尚不清楚,但您可以使用以下内容:

[A-Z\d]*\d[A-Z\d]*[A-Z][A-Z\d]*

这是一个包含至少一个数字和至少一个非数字字符的单词。请参阅demo

或许你可以使用:

\b\d[A-Z\d]*[A-Z][A-Z\d]*

dor一个以数字开头且至少包含非数字字符的单词。请参阅demo

或者,如果您想要正确组合这些正则表达式,请使用。

\b\d[A-Z]\d(X\d|\d{2}[A-Z]?)?\b

查看最终demo

答案 1 :(得分:0)

使用单个正则表达式模式:

strToSearch= " Alot of 1N1X1 people like to eat 3C191 cheese and I'm a 1A831B aka 1A8."
lstResults = [i[0] for i in re.findall(r'(\d[A-Z]\d{1,3}(X\d|[A-Z])?)', strToSearch)]

print(lstResults)

输出:

['1N1X1', '3C191', '1A831B', '1A8']

答案 2 :(得分:0)

如果你想找到混合了数字和字母的“单词”,最简单的方法是使用单词边界算子\b;但请注意,您需要使用r''字符串/转义代码中的\(在将来的Python版本中,无论如何都需要为\d执行此操作)。要匹配由单词边界分隔的任何字母数字字符序列,您可以使用

r'\b[0-9A-Z]+\b'

但是,这还不能保证至少有一个号码和至少一个字母。为此,我们将使用正零宽度前瞻断言(?= ),这意味着只有当包含的模式在该点匹配时,整个正则表达式才匹配。我们需要其中两个:一个确保至少有一个数字,一个至少有一个字母:

>>> p = r'\b(?=[0-9A-Z]*[0-9])(?=[0-9A-Z]*[A-Z])[0-9A-Z]+\b'
>>> re.findall(p, '1A A1 32 AA 1A123B')
['1A', 'A1', '1A123B']

只要至少有一位数字和一个字母,现在就会匹配包括33333AAAAAAAAAAA3A在内的所有内容。但是,如果模式始终以数字开头并且始终包含字母,则会变得稍微容易一些,例如:

>>> p = r'\b\d+[A-Z][0-9A-Z]*\b'
>>> re.findall(p, '1A A1 32 AA 1A123B')
['1A', '1A123B']

即。 A1不匹配,因为它不是以数字开头。