regex 整个组重复0次或更多次(用+分隔的一个或多个单词)

xghobddn  于 2023-01-06  发布在  其他
关注(0)|答案(2)|浏览(143)

我尝试在python中匹配用户输入的以+字符分隔的单词,并检查每个单词是否都在预定义的列表中。(单词由多个A-z字符组成)。例如,输入串foo应当与foo+barfoo+bar+baz以及每个被捕获的单词(不是+的)匹配。
到目前为止,我已经尝试了一些正则表达式,但最接近我得到的是这样的:

/^([A-z+]+)\+([A-z+]+)$/

然而,这只匹配有两个单词用+分隔的情况,我需要有 * 一个或多个 * 单词。如果我能以某种方式重复第二组(\+([A-z+]+))零次或多次,我上面的方法就会工作。因此,我的问题是:如何将捕获组重复零次或多次?
如果有更好的方法来做我正在做的事情,请让我知道。

7z5jn7bk

7z5jn7bk1#

您可以将模式编写为:

(?i)[A-Z]+(?:\+[A-Z]+)*$
    • 说明**
  • (?i)不区分大小写的内联修饰符
  • [A-Z]+匹配1+字符A-Z
  • (?:\+[A-Z]+)*(可选)重复匹配+,并再次匹配1+字符A-Z
  • $字符串结束

有关匹配项,请参见regex101 demo
例如

import re

predeterminedList = ["foo", "bar"]
strings = ["foo", "foo+bar", "foo+bar+baz", "test+abc"]
pattern = r"(?i)[A-Z]+(?:\+[A-Z]+)*$"

for s in strings:
    m = re.match(pattern, s)
    if m:
        words = m.group().split("+")
        intersect = bool(set(words) & set(predeterminedList))
        fmt = ','.join(predeterminedList)
        if intersect:
            print(f"'{s}' contains at least one of '{fmt}'")
        else:
            print(f"'{s}' contains none of '{fmt}'")

另一个选项是创建列出备选项的动态模式:

(?i)^(?:[A-Z]+\+)*(?:foo|bar)(?:\+[A-Z]+)*$

示例

import re

predeterminedList = ["foo", "bar"]
strings = ["foo", "foo+bar", "foo+bar+baz", "test+abc"]
pattern = rf"(?i)^(?:[A-Z]+\+)*(?:{'|'.join(predeterminedList)})(?:\+[A-Z]+)*$"

for s in strings:
    m = re.match(pattern, s)
    fmt = ','.join(predeterminedList)
    if m:
        print(f"'{s}' contains at least one of '{fmt}'")
    else:
        print(f"'{s}' contains none of '{fmt}'")

两者都将输出:

'foo' contains at least one of 'foo,bar'
'foo+bar' contains at least one of 'foo,bar'
'foo+bar+baz' contains at least one of 'foo,bar'
'test+abc' contains none of 'foo,bar'
bvhaajcl

bvhaajcl2#

我建议使用lookarounds的方法稍有不同:
图案:(?<=^|\+)(?=foo|baz)[^+]+
图案说明:
(?<=^|\+)-正向后查找-Assert前面的文本既不是^(字符串的开头)也不是+(我们的“字分隔符”)。
(?=foo|baz)-正向前看-Assert以下文本匹配(预定义列表中)一个单词
[^+]+-匹配+以外的一个或多个字符
Regex demo

相关问题