python - 具有不同字符数的正则表达式
问题描述
我需要创建一个正则表达式来验证字符串。字符串只能有几个字符,每个字符只能重复几次。
正则表达式应检查以下条件。
- 字符串只能包含a、b、c、d、e作为字符。
- 字符“ a ”最多可出现 2 次。
- 字符“ b ”最多可出现 3 次。
- 字符“ c ”最多可出现 3 次。
- 字符 ' d ' 最多可以出现 1 次。
- 字符' e '最多可以出现1次。
我知道这可以通过字符串函数来实现。但我正在尝试用正则表达式来做到这一点。
对此的任何帮助都将受到高度赞赏。
解决方案
可能,性能方面,最好的方法是使用 Python 原生字符串操作。
我会这样写:
lim=(('a',2),('b',3),('c',3),('d',1),('e',1))
results={}
for s in [list_of_many_strings]:
results[s]=bool(not(set(s)-set('abcde'))) and (not any(s.count(c)>x for c,x in lim))
这依赖于str.count(sub[, start[, end]])来计算字符串中子字符串的出现次数以及任何函数来测试任何条件是否为真。
由于您对性能感兴趣,您可以计算处理 100,000 个字符串可能需要多长时间timeit
:
import re
def f1(li):
results={}
lim=(('a',2),('b',3),('c',3),('d',1),('e',1))
for s in li:
results[s]=bool(not(set(s)-set('abcde'))) and (not any(s.count(c)>x for c,x in lim))
return results
def f2(li):
pat=re.compile(r'^a{0,2}b{0,3}c{0,3}d{0,1}e{0,1}$')
results={}
for s in li:
results[s]=True if pat.search(''.join(sorted(s))) else False
return results
def f3(li):
pat=re.compile(r'^(?!.*[^a-e])(?!(?:.*a){3})(?!(?:.*b){4})(?!(?:.*c){4})(?!(?:.*d){2})(?!(?:.*e){2}).+')
results={}
for s in li:
results[s]=True if pat.search(s) else False
return results
if __name__=='__main__':
import timeit
import random
s='abcdeabcdebc'
li=[''.join(random.sample(s,8)) for _ in range(100000)]
print(f1(li)==f2(li)==f3(li))
for f in (f1,f2,f3):
print(" {:^10s}{:.4f} secs".format(f.__name__, timeit.timeit("f(li)", setup="from __main__ import f, li", number=10)))
在我的电脑上,需要:
True
f1 0.8519 secs
f2 1.1235 secs
f3 1.3070 secs
推荐阅读
- django - 如何显示具有外键关系的记录的详细信息
- c - 使用不同类型的字段填充结构
- python - 如何摆脱 Choropleth 的白色背景?
- listview - 插入新记录后如何重新加载列表?
- java - Gettig CertificateException:Playframework java 应用程序中的“找不到与本地主机匹配的名称”
- undefined - 为什么fabricjs kclass fromobject在新版本上返回未定义?
- c# - 使用 linq 从 Json 获取 ID 的名称
- html - MS Outlook 365 HTML 表格 VALIGN
- sublimetext3 - 如何在 Sublime Text 3 中重命名文件选项卡
- azure-stream-analytics - 将部署在 ACI 上的 ML 模型与 Azure 中的流分析结合使用