使用正则表达式查找括号之间的特定字符串(包括括号)
Using regular expression to find specific strings between parentheses (including parentheses)
我正在尝试使用正则表达式在如下所示的字符串中查找括号之间的特定字符串:
foo = '((peach W/O juice) OR apple OR (pear W/O water) OR kiwi OR (lychee AND sugar) OR (pineapple W/O salt))'
具体来说,我只想查找 (peach W/O juice)
、(pear W/O water)
和 (pineapple W/O salt)
。
我尝试了lookahead
和lookbehind
,但无法获得正确的结果。
例如,当我执行以下正则表达式时:
import re
regex = '(?<=[\s\(])\([^\)].*\sW/O\s[^\)].*\)(?=[\)\s])'
re.findall(regex, foo)
我得到了整个字符串:
['(peach W/O juice) OR apple OR (pear W/O water) OR kiwi OR (lychee AND sugar) OR (pineapple W/O salt)']
编辑:
我发现了问题:
而不是 [\)].*
,我应该 [\)]*
,这会给我正确的结果:
regex = '(?<=[\s\(])\([^\)]*\sW/O\s[^\)]*\)(?=[\)\s])'
re.findall(regex, foo)
['(peach W/O juice)', '(pear W/O water)', '(pineapple W/O salt)']
我认为你的问题是你的 .*
运算符太贪心了——如果你不在它们后面加上 ?
,它们会尽可能多地消耗:.*?
.另外,请注意,由于您 想要 括号,因此您不需要 lookahead/lookbehind 操作;他们将排除他们找到的括号。
我决定重写它,而不是完全调试您的正则表达式:
>>> import re
>>> foo ='((peach W/O juice) OR apple OR (pear W/O water) OR kiwi OR (lychee AND sugar) OR (pineapple W/O salt))'
>>> regex = '\([a-zA-Z ]*?W/O.*?\)'
>>> re.findall(regex, foo)
['(peach W/O juice)', '(pear W/O water)', '(pineapple W/O salt)']
细目如下:
\(
捕获前导括号 - 请注意它已转义
[a-zA-Z ]
捕获所有字母字符和一个 space(注意右括号前 Z 之后的 space)我用这个代替 .
所以没有其他括号将被捕获。使用句点运算符会导致 (lychee AND sugar) OR (pineapple W/O salt)
被捕获为一个匹配项。
*?
*
导致括号中的字符匹配 0 次或多次,但 ?
表示 只捕获所需数量匹配
W/O
捕获了您正在寻找的 "W/O"
.*?
捕获更多字符(同样,由于 ?
而非贪婪)
\)
捕获尾随括号
由于要在结果中包含括号,因此不需要使用环视。您可以使用不包含右括号的字符 class。这样,你确定W/O在括号之间:
re.findall(r'\([^()]* W/O [^)]*\)', foo)
我正在尝试使用正则表达式在如下所示的字符串中查找括号之间的特定字符串:
foo = '((peach W/O juice) OR apple OR (pear W/O water) OR kiwi OR (lychee AND sugar) OR (pineapple W/O salt))'
具体来说,我只想查找 (peach W/O juice)
、(pear W/O water)
和 (pineapple W/O salt)
。
我尝试了lookahead
和lookbehind
,但无法获得正确的结果。
例如,当我执行以下正则表达式时:
import re
regex = '(?<=[\s\(])\([^\)].*\sW/O\s[^\)].*\)(?=[\)\s])'
re.findall(regex, foo)
我得到了整个字符串:
['(peach W/O juice) OR apple OR (pear W/O water) OR kiwi OR (lychee AND sugar) OR (pineapple W/O salt)']
编辑:
我发现了问题:
而不是 [\)].*
,我应该 [\)]*
,这会给我正确的结果:
regex = '(?<=[\s\(])\([^\)]*\sW/O\s[^\)]*\)(?=[\)\s])'
re.findall(regex, foo)
['(peach W/O juice)', '(pear W/O water)', '(pineapple W/O salt)']
我认为你的问题是你的 .*
运算符太贪心了——如果你不在它们后面加上 ?
,它们会尽可能多地消耗:.*?
.另外,请注意,由于您 想要 括号,因此您不需要 lookahead/lookbehind 操作;他们将排除他们找到的括号。
我决定重写它,而不是完全调试您的正则表达式:
>>> import re
>>> foo ='((peach W/O juice) OR apple OR (pear W/O water) OR kiwi OR (lychee AND sugar) OR (pineapple W/O salt))'
>>> regex = '\([a-zA-Z ]*?W/O.*?\)'
>>> re.findall(regex, foo)
['(peach W/O juice)', '(pear W/O water)', '(pineapple W/O salt)']
细目如下:
\(
捕获前导括号 - 请注意它已转义
[a-zA-Z ]
捕获所有字母字符和一个 space(注意右括号前 Z 之后的 space)我用这个代替 .
所以没有其他括号将被捕获。使用句点运算符会导致 (lychee AND sugar) OR (pineapple W/O salt)
被捕获为一个匹配项。
*?
*
导致括号中的字符匹配 0 次或多次,但 ?
表示 只捕获所需数量匹配
W/O
捕获了您正在寻找的 "W/O"
.*?
捕获更多字符(同样,由于 ?
而非贪婪)
\)
捕获尾随括号
由于要在结果中包含括号,因此不需要使用环视。您可以使用不包含右括号的字符 class。这样,你确定W/O在括号之间:
re.findall(r'\([^()]* W/O [^)]*\)', foo)