Python正则表达式匹配具有重复辅音的单词
首先,这是家庭作业。(我不能在标题中使用标签,并且底部的标签列表中没有显示任何作业,因此请让我知道我是否应该编辑与此相关的其他内容) 因此,我一直在阅读python文档并进行清理,找到了一些接近我想要的解决方案,但并不精确 我有一本字典,我把它读入一个字符串:Python正则表达式匹配具有重复辅音的单词,python,regex,Python,Regex,首先,这是家庭作业。(我不能在标题中使用标签,并且底部的标签列表中没有显示任何作业,因此请让我知道我是否应该编辑与此相关的其他内容) 因此,我一直在阅读python文档并进行清理,找到了一些接近我想要的解决方案,但并不精确 我有一本字典,我把它读入一个字符串: a aa aabbaa ... z 我们正在对这些数据使用各种正则表达式模式。 这里的具体问题是返回与模式匹配的单词列表,而不是每个匹配中包含组的元组 例如: 给定此词典的子集,如: someword sommmmmeword some
a
aa
aabbaa
...
z
我们正在对这些数据使用各种正则表达式模式。
这里的具体问题是返回与模式匹配的单词列表,而不是每个匹配中包含组的元组
例如:
给定此词典的子集,如:
someword
sommmmmeword
someworddddd
sooooomeword
我想返回:
['sommmmmword', 'someworddddd']
不是:
编辑:
我在上面这个例子背后的理由是,我想看看如何避免第二次忽略结果。这并不是说:
res = re.match(re.compile(r'pattern'), dictionary)
return [r[0] for r in res]
我特别想要一个机制,我可以只使用:
return re.match(re.compile(r'pattern'), dictionary)
我知道这听起来很傻,但我这样做是为了真正深入研究正则表达式。我在底部提到这一点
这就是我尝试过的:
# learned about back refs
r'\b([b-z&&[^eiou]])\1+\b' -> # nothing
# back refs were weird, I want to match something N times
r'\b[b-z&&[^eiou]]{2}\b' -> # nothing
在测试的某个地方,我注意到一个模式返回类似于'\nsomeword'
的内容。我不知道它是什么,但如果我再次找到该模式,我会将其包含在这里,以确保完整性
# Maybe the \b word markers don't work how I think?
r'.*[b-z&&[^eiou]]{2}' -> # still nothing
# Okay lets just try to match something in between anything
r'.*[b-z&&[^eiou]].*' -> # nope
# Since its words, maybe I should be more explicit.
r'[a-z]*[b-z&&[^eiou]][a-z]*' -> # still nope
# Decided to go back to grouping.
r'([b-z&&[^eiou]])(\1)' # I realize set difference may be the issue
# I saw someone (on SO) use set difference claiming it works
# but I gave up on it...
# OKAY getting close
r'(([b-df-hj-np-tv-xz])(\2))' -> [('ll', 'l', 'l'), ...]
# Trying the the previous ones without set difference
r'\b(.*(?:[b-df-hj-np-tv-xz]{3}).*)\b' -> # returned everything (all words)
# Here I realize I need a non-greedy leading pattern (.* -> .*?)
r'\b(.*?(?:[b-df-hj-np-tv-xz]{3}).*)\b' -> # still everything
# Maybe I need the comma in {3,} to get anything 3 or more
r'\b(.*?(?:[b-df-hj-np-tv-xz]{3,}).*)\b' -> # still everything
# okay I'll try a 1 line test just in case
r'\b(.*?([b-df-hj-np-tv-xz])(\2{3,}).*)\b'
# Using 'asdfdffff' -> [('asdfdffff', 'f', 'fff')]
# Using dictionary -> [] # WAIT WHAT?!
最后一个如何工作?也许没有3+个重复的辅音词?我正在学校服务器上使用/usr/share/dict/cracklib small
,我想大概有50000个单词
我仍在努力,但任何建议都会很棒
有一件事我觉得很奇怪,那就是你不能引用一个未捕获的组。如果我只想输出完整的单词,我会使用(?:…)来避免捕获,但是我不能返回引用。显然,我可以留下捕获,循环结果,过滤掉多余的东西,但我绝对想用正则表达式来解决这个问题
也许有一种方法可以实现非捕获,但仍然允许反向引用?或者可能有一个完全不同的表达式我还没有测试过。这里有几点需要考虑:
re.findall
获取所有结果,而不是re.match
(仅搜索1个匹配项,且仅在字符串开头)[b-z&&[^eiou]]
是一个Java/ICU正则表达式,Pythonre
不支持此语法。在Python中,您可以重新定义范围以跳过元音,也可以使用(?![eiou])[b-z]
re.findall
的“额外”值,请不要使用捕获组。如果需要反向引用,请使用re.finditer
而不是re.findall
并访问每个匹配项的.group()
当你努力完成作业后,可以在这里问一下家庭作业:)你能分享一下
['sommmmmmword','sommwordddddd']
和[('sommmword','mmmmmm',…),…]
背后的逻辑吗?啊,是的,如果这看起来让人困惑的话,很抱歉。我输入了一个edit.1)使用re.findall
获取所有结果,而不是re.match
(只搜索1个匹配项,并且只在字符串开头)。2) [b-z&&[^eiou]]
是一个Java/ICU正则表达式,Pythonre
不支持此语法。3) 要避免元组中带有re.findall
的“额外”值,请不要使用捕获组。如果您需要反向引用,请使用re.finditer
而不是re.findall
,并访问每个匹配项的.group()
。这就是您要查找的吗?啊,我使用的是fiindall,我只是输入了错误的示例。但我没有尝试finditer!我以为那只是芬德尔的发电机。我会在回家后测试一下!非常感谢。另外,作为一个旁注,我是否可以使用\1{N}而不将其分组,而不是显式地说“\1\1\1…”来收集匹配的N个副本?您可以使用带有反向引用(=量化反向引用)的量词,方式与任何原子相同:\1{4}
。看见
# Maybe the \b word markers don't work how I think?
r'.*[b-z&&[^eiou]]{2}' -> # still nothing
# Okay lets just try to match something in between anything
r'.*[b-z&&[^eiou]].*' -> # nope
# Since its words, maybe I should be more explicit.
r'[a-z]*[b-z&&[^eiou]][a-z]*' -> # still nope
# Decided to go back to grouping.
r'([b-z&&[^eiou]])(\1)' # I realize set difference may be the issue
# I saw someone (on SO) use set difference claiming it works
# but I gave up on it...
# OKAY getting close
r'(([b-df-hj-np-tv-xz])(\2))' -> [('ll', 'l', 'l'), ...]
# Trying the the previous ones without set difference
r'\b(.*(?:[b-df-hj-np-tv-xz]{3}).*)\b' -> # returned everything (all words)
# Here I realize I need a non-greedy leading pattern (.* -> .*?)
r'\b(.*?(?:[b-df-hj-np-tv-xz]{3}).*)\b' -> # still everything
# Maybe I need the comma in {3,} to get anything 3 or more
r'\b(.*?(?:[b-df-hj-np-tv-xz]{3,}).*)\b' -> # still everything
# okay I'll try a 1 line test just in case
r'\b(.*?([b-df-hj-np-tv-xz])(\2{3,}).*)\b'
# Using 'asdfdffff' -> [('asdfdffff', 'f', 'fff')]
# Using dictionary -> [] # WAIT WHAT?!
import re
s = """someword
sommmmmeword
someworddddd
sooooomeword"""
res =[x.group() for x in re.finditer(r"\w*([b-df-hj-np-tv-xz])\1\w*", s)]
print(res)
# => ['sommmmmeword', 'someworddddd']