python - 匹配正则表达式排列而不重复但有一个扭曲
问题描述
似乎我找不到解决这个问题的方法,这可能是一个简单的问题:我希望能够用一个简单的正则表达式匹配 5 个指定数字的所有可能排列,而无需重复,所有数字都必须使用。所以,对于这个序列:
12345
有效的排列是:
54321
但
55555
无效。
但是,如果提供的数字有一次或多次相同的数字,那么只有在这种情况下,接受的排列才会有那些重复的数字,但每个数字只能使用一次。例如,如果提供的号码是:
55432
我们看到 5 提供了 2 次,因此它必须在每个排列中也出现两次,并且一些接受的答案是:
32545
45523
但这是错误的:
55523
(并非所有原始数字都被使用,并且 5 重复了两次以上)
我非常接近解决这个问题:
(?:([43210])(?!.*\1)){5}
但不幸的是,当提供多个相同的数字(如 43211)时,它不起作用。
解决方案
解决这个问题的一种方法是从搜索数字中创建一个字符类,并构建一个正则表达式来搜索该类中与搜索字符串中一样多的数字。然后,您可以根据排序匹配字符串与排序搜索字符串相同来过滤正则表达式结果。例如:
import re
def find_perms(search, text):
search = sorted(search)
regex = re.compile(rf'\b[{"".join(search)}]{{{len(search)}}}\b')
matches = [m for m in regex.findall(text) if sorted(m) == search]
return matches
print(find_perms('54321', '12345 54321 55432'))
print(find_perms('23455', '12345 54321 55432'))
print(find_perms('24455', '12345 54321 55432'))
输出:
['12345', '54321']
['55432']
[]
请注意,我\b
在正则表达式中包含了单词边界 ( ),以便(例如)12345
不匹配654321
。如果您还想匹配子字符串,只需从正则表达式中删除单词边界。
推荐阅读
- flutter - 不从 Firebase 检索 CurrentUser 特定数据 - Flutter
- sql - 通过语句计算从每个组中获得的平均值的平均值
- javascript - 如何进行长时间的网页加载?
- c - 如何使用 sprintf 显示 64 位无符号整数?
- vim - 在 Vim 中,在指定的跳转位置打开一个新窗口
- asp.net-mvc - ASP .NET CORE MVC 3.1 - 创建新 Intent 时出现 Invalid Column Name 错误
- laravel - 如何在 Ceate Crud 中显示仅选择启用的文件
- python - 如何仅在 Gitlab 中更改的文件上运行 pylint?
- visual-studio - Visual Basic - 从 FOR 循环中删除值
- python - 在多列上使用 Sum() 和 Groupby