想象一下这是一个大文本的一部分:
东西(word1 / Word2 / w0rd3)东西,东西(word4 / word5)东西/东西(word6)东西(word7 / word8 / word9)东西/东西,(w0rd10 / word11)东西(word12)东西(Word13 / w0rd14 / word15)填充材料(word16 / word17)。
我想要这些话。结果必须匹配:
word1
Word2
w0rd3
word4
word5
word6
word7
word8
word9
w0rd10
word11
word12
Word13
w0rd14
word15
word16
word17
结果也不应该像这样:
(word1) or (word1/Word2/w0rd3)
基本上不允许(或)或 /
我尝试过的事情:
\((\w+)\/(\w+)\/(\w+)\)[^(]*\((\w+)\/(\w+)\)[^(]*\((\w+)\)
这与那些单词匹配,但是我必须重复它,因为存在许多不干净的单词。我也尝试过txt2re,但是它也是重复的,并且不是一行正则表达式。如果我想在在线正则表达式评估器上使用它,并且没有任何代码可访问,那么我需要一行和简短的正则表达式。我首选的引擎是Python和C#。
更新:
我在文本中添加了/
。也很抱歉更改了接受的答案,所有答案在某种程度上都是正确的,但是我必须在这里选择最快,最高效的正则表达式。
答案 0 :(得分:3)
一种常见的解决方案是检查前面是否有)
收盘,而中间没有(
收盘。
\w+\b(?=[^)(]*\))
\w+
匹配一个或多个word characters,后跟\b
word boundary (?=[^)(]*\))
look,如果关闭)
领先于两者之间的任何non (
)
因此,此模式之前不会检查(
的开头,但是通常不需要。
答案 1 :(得分:2)
您可以使用一个捕获组,该捕获组将由re.findall返回,并将括号之间的所有内容与正斜杠作为定界符进行匹配。
然后在结果中您可以在正斜杠上进行分割:
\((\w+(?:/\w+)*)\)
说明
\(
比赛开头括号(
捕获组
\w+
匹配1个以上的字符字符(?:/\w+)*
匹配/
和它的1+个单词字符0+次)
关闭捕获组\)
匹配右括号如果您想匹配多个单词字符,则可以使用否定的字符类[^()/]+
,不匹配括号或正斜杠:
\(([^()/]+(?:/[^()/]+)*)\)
例如:
import re
regex = r"\(([^()/]+(?:/[^()/]+)*)\)"
test_str = "stuff (word1/Word2/w0rd3) stuff, stuff (word4/word5) stuff stuff (word6) stuff (word7/word8/word9) stuff stuff, (w0rd10/word11) stuff stuff (word12) stuff (Word13/w0rd14/word15) stuff-stuff stuff (word16/word17)."
res = list(map(lambda x: x.split('/'), re.findall(regex, test_str)))
答案 2 :(得分:2)
代替匹配单词,您可以编写匹配非单词的正则表达式,并用正则表达式分割:
\)?[^)]+?\(|\).+|/
无字是:
答案 3 :(得分:1)
将findall
与后置断言一起使用
(?<=[(/])\w+
>>> re.findall(r'(?<=[(/])\w+', input_string)
['word1', 'Word2', 'w0rd3', 'word4', 'word5', 'word6', 'word7', 'word8', 'word9', 'w0rd10', 'word11', 'word12', 'Word13', 'w0rd14', 'word15', 'word16', 'word17']
说明
(?<=[(/])\w+
正向
(?<=[(/])
后面
- 断言以下正则表达式匹配
- 匹配列表
[(/]
中存在的单个字符
(
或/
匹配一个字符\w+
匹配任何单词字符(等于[a-zA-Z0-9_]
)
+
量词-在一次和无限次之间进行匹配,并尽可能多地匹配,并根据需要返回(贪婪)