我的文字看起来像:
我的名字是(理查德),我做不到 [无论什么(杰克)做不到]和 (罗伯特)也是一样[不像 (贝蒂)]谢谢(吉尔)
目标是使用正则表达式进行搜索,以查找出现在任何括号之间的文本中任何位置的所有带括号的名称。
所以在上面的文字中,我要找的结果是:
答案 0 :(得分:3)
您可以分两步完成:
step1 :使用以下方式匹配所有括号内容:
\[[^\]]*\]
并将其替换为''
step2 :使用以下方式匹配所有剩余的括号名称(全局):
\([^)]*\)
答案 1 :(得分:2)
你没有说你正在使用什么语言,所以这里有一些Python:
>>> import re
>>> REGEX = re.compile(r'(?:[^[(]+|\(([^)]*)\)|\[[^]]*])')
>>> s="""My name is (Richard) and I cannot do [whatever (Jack) can't do] and (Robert) is the same way [unlike (Betty)] thanks (Jill)"""
>>> filter(None, REGEX.findall(s))
输出结果为:
['Richard', 'Robert', 'Jill']
有一点需要注意,这不适用于任意嵌套。它真正设计的唯一嵌套是问题中提到的方括号中的一层parens。只使用正则表达式无法进行任意嵌套。 (这是the pumping lemma for regular languages的结果。)
正则表达式查找没有括号或parens的文本块,用parens括起来的文本块,以及用括号括起来的文本块。仅捕获parens中的文本(不在方括号中)。 Python的findall
按顺序查找正则表达式的所有匹配项。在某些语言中,您可能需要编写一个循环来重复匹配。对于非paren匹配,findall
会在结果列表中插入一个空字符串,因此对filter
的调用会删除这些字符串。
答案 2 :(得分:1)
IF 您正在使用.NET,您可以执行以下操作:
"(?<!\[.*?)(?<name>\(\w+\))(?>!.*\])"
答案 3 :(得分:0)
对于单个正则表达式来说,这不是最好的工作 - 例如,您是否考虑过复制字符串然后删除方括号之间的所有内容?那么从括号内提取东西就相当简单。或者,您可以编写一个非常基本的解析器来标记行(正常文本,方括号文本和括号文本,我想),然后解析生成的树;它最初会有更多的工作,但如果你以后想让这个行为变得更复杂,那么生活会更简单。
话虽如此,/(?:(?:^|\])[^\[]*)\((.*?)\)/
为您的测试用例提供了诀窍(但如果您的[
和]
未正确匹配,几乎肯定会有一些奇怪的行为,而我我不相信它有效率。
快速(PHP)测试用例:
preg_match_all('/(?:(?:^|\])[^\[]*)\((.*?)\)/', "My name is ... (Jill)", $m);
print(implode(", ", $m[1]));
输出:
Richard, Robert, Jill
答案 4 :(得分:0)
>>> s="My name is (Richard) and I cannot do [whatever (Jack) can't do (Jill) can] and (Robert) is the same way [unlike (Betty)] thanks (Jill)"
>>> for item in s.split("]"):
... st = item.split("[")[0]
... if ")" in st:
... for i in st.split(")"):
... if "(" in i:
... print i.split("(")[-1]
...
Richard
Robert
Jill
答案 5 :(得分:0)
所以你想要正则表达式匹配名称,而不是括号括起来?这应该这样做:
[^()]+(?=\)[^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*$)
与其他答案一样,我对你的目标字符串做了一些假设,比如期望括号和方括号正确平衡而不是嵌套。
我说它应该工作,因为虽然我已经测试了它,但我不知道你正在用什么语言/工具来进行正则表达式匹配。如果我们有这些信息,我们可以提供更高质量的答案;所有的正则表达式都不是平等的。