Python RegEx仅匹配内部正则表达式

时间:2015-08-04 20:15:07

标签: python regex

我之前在StackOverflow上找到了这个问题的解决方案,但无法再找到解决方案。 我想从字符串中提取一个模式。

my_string ='hello ,mister synonyms: fine, of high quality, of a high standard, quality, superior; More'

我想提取'fine, of high quality, of a high standard, quality, superior'

我用过

match_obj = re.search(r'(synonyms: )((\w+,|; )+)', my_string)
print(match_obj.group(2))

仅提供'fine,' 我知道在这种情况下我为嵌套括号编写正则表达式的方式有问题,但我无法找到正确的写入方式。

4 个答案:

答案 0 :(得分:2)

您可以首先使用逗号分隔值获取子字符串(您可以使用(?<=synonyms: )[^;]+正则表达式,只能匹配;子字符串后synonyms:以外的1个或多个字符,以及然后用\s*,\s*正则表达式进行拆分(它也将修剪值,这要归功于与\s*匹配的空白)以获得必要的值:

import re
p = re.compile(r'(?<=synonyms: )[^;]+')
test_str = "hello ,mister synonyms: fine, of high quality, of a high standard, quality, superior; More"
o = re.search(p, test_str)
if o:
    s = o.group()
    print re.split(r"\s*,\s*", s)

请参阅IDEONE demo

更新

由于您的目的是学习捕获和非捕获组,因此这是您的固定正则表达式:

(synonyms: )((?:\s*\w+,?)+)

并解释:

  • (synonyms: ) - 第一个与字面synonyms:
  • 匹配的捕获组
  • ((?:\s*\w+,?)+) - 匹配的第二个捕获组
    • (?:\s*\w+,?)+ - 一个或多个非捕获序列(即它不会存储在堆栈中)
      • \s* - 0个或更多空格字符
      • \w+ - 一个或多个单词字符([A-Za-z0-9_]
      • ,? - 0或1个逗号

Demo is available here

注意事项:

  1. 您不必捕获文字文本。你已经了解它们,没有任何意义。

  2. Python re引擎不记得.NET中的多个捕获组(我们有.Captures属性),因此,我们不能使用捕获组来获取所有单独的逗号分隔价值很容易。 Python也不支持正则表达式\G来获得连续匹配。

  3. 要获取单个条目,在Python中,我们必须将获取字符串拆分为第二步(当然,如果需要)。

  4. 考虑到优化,您可以看到在正则表达式中,(?:\s*\w+,?)+部分看起来很棘手,但重点是所有3个组件 - \s\w和{ {1}} 无法匹配相同的文字。当您编写真正复杂的正则表达式并将,量词设置为整个组时,遵循相同的策略非常重要。

答案 1 :(得分:1)

如果您只想匹配"synonyms: "";"之间的任何内容,则可以使用以下方法之一:

(synonyms: )([\w, ]+|[^;])+
(synonyms: )(\w+, [^;]+)+
(synonyms: )(.+)(?=;)
(synonyms: )([^;]+)

答案 2 :(得分:1)

如果我理解正确,您希望在synonyms:之后匹配分号后的所有内容?

r'(synonyms: )([\w, ]+)'

查看实际操作:https://regex101.com/r/jI0dV4/1

我认为你的正则表达式中的缺陷基本上是|的位置。 这使得正则表达式匹配 \w, ;__表示空格)

请注意,使用圆括号分组始终会引入新的捕获组。 我用方括号列出了允许的字符。

如果您按照link进行操作,可以尝试不同的内容并获得即时结果和解释。

答案 3 :(得分:1)

这将捕获“synonyms:”和“;”之间的所有内容成一个字符串。因为正向后视(?<=synonyms: )是零宽度,非捕获断言,所以唯一的捕获组将为零([^;]+)

test_str = "hello ,mister synonyms: fine, of high quality, of a high standard, quality, superior; More"
regex = re.compile(r'(?<=synonyms: )([^;]+)')
string = regex.search(test_str).group(0)

print(string)