使用Regex Python 3指定多个匹配“LIGAND”

wn9m85ua  于 2023-11-20  发布在  Python
关注(0)|答案(2)|浏览(116)

我是正则表达式的新手,不知道该怎么问这个问题,但我会尽我所能。
下面是我正在使用的一个简单表达式:

"^[0-9]{13}$"

字符串
根据Python文档,我可以设置这样一个范围来匹配一个长度在13到20个字符之间的数字字符串,例如:

"^[0-9]{13,20}$"


我的问题是,我如何从一个范围中排除某些“长度”?例如:

"^[0-9]{13,20 EXCEPT for 15 or 17}$"


在这个例子中,我想包括13和20之间的任何长度,除了15和17。
这可能吗?
我看过Python 3 regex文档,我个人无法找到一种方法来做到这一点,但我也没有经验,所以我可能会忽略一些东西。

e37o9pze

e37o9pze1#

在第二个模式中,你可以用一个 * 自定义/受限 * 的^(?!(.{15}|.{17})$)来替换字符串^的开头(这是基于要排除的长度构建的)。这将确保匹配每个字符串的开头,但仅当这个字符串的长度不是15或17个字符时。

Use 

    ^(?!(.{15}|.{17})$)[0-9]{13,20}$
instead of 

    ^[0-9]{13,20}$

字符串
下面是处理不同不连续范围的通用代码:

# feel free to adjust the values
(l, r), excep = [13, 20], [15, 17]

to_excl = "|".join(".{%s}" % n for n in excep)

pat = re.compile(r"^(?!(%s)$)[0-9]{%s,%s}$" % (to_excl, l, r))


测试/输出:

for t in text:
    print(
        f"{t:<22}", f"{len(t):<4}",
        "match" if pat.match(t) else "no-match"
    )
    
01234                  5    no-match
012345678901234        15   no-match
0123456789012345       16   match
01234567890123456      17   no-match
012345678901234567     18   match
012345678901234567890  21   no-match


使用的输入:

from string import digits
s = digits; lens = [5, 15, 16, 17, 18, 21]
text = [s * (l // 10) + s[:l % 10] for l in lens]
   
['01234',
 '012345678901234',
 '0123456789012345',
 '01234567890123456',
 '012345678901234567',
 '012345678901234567890']

iibxawm4

iibxawm42#

嗯.是的,你可以,但这将需要不止一个量词。
With alternatives

^
(?:
  [0-9]{13,14}   # 13 or 14
|
  [0-9]{16}      # or 16
|
  [0-9]{18,20}   # or 18, 19, 20.
)
$

字符串
With lookaheads

^
(?!.{15}$)(?!.{17}$)    # Assure that the length is neither 15 nor 17,
[0-9]{13,20}            # and at the same time, 13 <= length <= 20.
$


With lookbehinds

^
[0-9]{13,20}            # Basically the same pattern,
(?<!^.{15})(?<!^.{17})  # just inverted.
$


使用正常的Python代码:

# Note the lack of anchors and the use of .fullmatch()
# That method is used here since it is more readable,
# and it automatically adds anchors.

_13_to_20_digits = re.compile('[0-9]{13,20}')

if _13_to_20_digits.fullmatch(text) and len(text) not in (15, 17):
  frobnicate()


选择一个。你喜欢哪一个。我个人喜欢最后一个,因为它非常清晰,即使对于那些不知道正则表达式的人来说。

相关问题