我之前在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,'
我知道在这种情况下我为嵌套括号编写正则表达式的方式有问题,但我无法找到正确的写入方式。
答案 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个逗号注意事项:
您不必捕获文字文本。你已经了解它们,没有任何意义。
Python re
引擎不记得.NET中的多个捕获组(我们有.Captures
属性),因此,我们不能使用捕获组来获取所有单独的逗号分隔价值很容易。 Python也不支持正则表达式\G
来获得连续匹配。
要获取单个条目,在Python中,我们必须将获取字符串拆分为第二步(当然,如果需要)。
考虑到优化,您可以看到在正则表达式中,(?:\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)