Python正则表达式匹配具有重复辅音的单词

2024-06-07 15:09:43 发布

您现在位置:Python中文网/ 问答频道 /正文

首先,这是家庭作业。(我无法在标题中使用标记,并且底部的标记列表中没有显示任何作业,因此请让我知道是否需要编辑与此相关的其他内容)。在

因此,我一直在阅读python文档并进行搜索,找到了几个与我想要的非常接近但并不精确的解决方案。在

我有一本字典,我把它读入一个字符串:

a
aa
aabbaa
...
z

我们正在对这些数据使用各种regex模式。 这里的具体问题是返回与模式匹配的单词列表,而不是每个匹配项中包含组的元组。在

例如:

给出本词典的一个子集,如:

^{pr2}$

我想回来:

['sommmmmword', 'someworddddd']

不是:

[('sommmmword', 'mmmmm', ...), ...] # or any other variant

编辑:

我在上面的例子背后的理由是,我想看看如何避免再次传递结果。这不是说:

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个单词。在

我仍在努力,但任何建议都会很棒。在

有一件事我很好奇,那就是你不能反向引用一个非捕获组。如果我只想输出完整的单词,我使用(?)?:…)为了避免被捕获,但那时候我不能回引用。显然,我可以离开捕获,循环结果并过滤掉多余的东西,但我绝对想用正则表达式来解决这个问题!在

也许有一种方法可以做到不捕获,但仍然允许反向引用?或许还有一个完全不同的表达方式我还没有测试过。在


Tags: thetoinredfmatchnp模式
1条回答
网友
1楼 · 发布于 2024-06-07 15:09:43

以下是一些需要考虑的问题:

  1. 使用re.findall获得所有结果,而不是re.match(它只搜索1个匹配项,并且只在字符串开始处搜索)。

  2. [b-z&&[^eiou]]是一个Java/ICU regex,Pythonre不支持此语法。在Python中,可以重新定义范围以跳过元音,也可以使用(?![eiou])[b-z]

  3. 为了避免带有re.findall的元组中的“额外”值,不要使用捕捉组。如果需要反向引用,请使用re.finditer而不是re.findall,并访问每个匹配项的.group()

回到问题上来,如何使用backreference并仍然得到整个匹配,这里有一个working demo

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']

相关问题 更多 >

    热门问题