- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在询问 Python 中的部分正则表达式匹配。
例如:
如果你有一个字符串:
string = 'foo bar cat dog elephant barn yarn p n a'
还有一个正则表达式:
pattern = r'foo bar cat barn yard p n a f'
以下为真:
re.match(pattern, string)
将返回 None
。re.search(pattern, string)
也会返回 None
尽管我们都可以看到模式的第一部分匹配字符串的第一部分。
所以不是搜索字符串中的整个模式,有没有办法查看字符串与模式匹配的百分比?
最佳答案
是的,可以进行部分正则表达式匹配
我一直在研究部分匹配的想法,并在搜索过程中找到了这个 Q。我找到了一种方法来做我需要做的事情,我想我会把它贴在这里。
这不是速度恶魔。可能仅在速度不是问题的情况下才有用。
此函数找到正则表达式的最佳部分匹配并返回匹配文本。
>>> def partial_match(regex, string, flags=0, op=re.match):
... """
... Matches a regular expression to a string incrementally, retaining the
... best substring matched.
... :param regex: The regular expression to apply to the string.
... :param string: The target string.
... :param flags: re module flags, e.g.: `re.I`
... :param op: Either of re.match (default) or re.search.
... :return: The substring of the best partial match.
... """
... m = op(regex, string, flags)
... if m:
... return m.group(0)
... final = None
... for i in range(1, len(regex) + 1):
... try:
... m = op(regex[:i], string, flags)
... if m:
... final = m.group(0)
... except re.error:
... pass
... return final
...
测试:
>>> partial_match(r".*l.*?iardvark", "bluebird")
'bluebi'
>>>
>>> partial_match(r"l.*?iardvark", "bluebird")
>>> # None was returned. Try again with search...
>>>
>>> partial_match(r"l.*?iardvark", "bluebird", op=re.search)
'luebi'
>>>
>>> string = 'foo bar cat dog elephant barn yarn p n a'
>>> pattern = r'foo bar cat barn yard p n a f'
>>>
>>> partial_match(pattern, string)
'foo bar cat '
>>>
>>> partial_match(r".* (zoo){1,3}ran away", "the fox at the "
... "zoozoozoozoozoo is "
... "happy")
'the fox at the zoozoozoo'
表现如预期。该算法不断尝试将尽可能多的表达式与目标字符串匹配。它一直持续到整个表达式与目标字符串匹配为止,保留最佳的部分匹配。
好的。现在让我们看看它到底有多慢......
>>> import cProfile as cprof, random as rand, re
>>>
>>> # targets = ['lazy: that# fox~ The; little@ quick! lamb^ dog~ ',
>>> # << 999 more random strings of random length >>]
>>>
>>> words = """The; quick! brown? fox~ jumped, over. the! lazy: dog~
... Mary? had. a little- lamb, a& little@ lamb^ {was} she... and,,,
... [everywhere] that# Mary* went=, the. "lamb" was; sure() (to) be.
... """.split()
...
>>> targets = [' '.join(rand.choices(words, k=rand.randint(1, 100)))
... for _ in range(1000)]
...
>>> exprs = ['.*?&', '.*(jumped|and|;)', '.{1,100}[\\.,;&#^]', '.*?!',
... '.*?dog. .?lamb.?', '.*?@', 'lamb', 'Mary']
...
>>> partial_match_script = """
... for t in targets:
... for e in exprs:
... m = partial_match(e, t)
... """
...
>>> match_script = """
... for t in targets:
... for e in exprs:
... m = re.match(e, t)
... """
...
>>> cprof.run(match_script)
32003 function calls in 0.032 seconds
>>>
>>> cprof.run(partial_match_script)
261949 function calls (258167 primitive calls) in 0.230 seconds
与 re.match()
直接运行它,它只需要进行常规匹配并且大部分时间都失败可能不是函数性能的公平比较.更好的比较是与支持模糊匹配的模块进行比较,我在下面做了这样的事情……而且该功能毕竟没问题。
可以使用 re.sre_parse
和/或 re.sre_compile
模块开发性能更高的解决方案。看起来所有要引用的文档都在源代码和网络上的零碎信息中,如 https://www.programcreek.com/python/example/1434/sre_parse
对于这些模块,我认为可能有一种方法可以通过标记或子表达式逐步应用正则表达式,而不是像我所做的那样通过单个字符。
此外,正如有人评论的那样,regex 包具有模糊匹配功能 ( https://pypi.org/project/regex/ ) - 但它的行为略有不同,并且可能允许部分匹配中出现意外字符。
>>> import regex
>>>
>>> regex.match(r"(?:a.b.c.d){d}", "a.b.c", regex.ENHANCEMATCH).group(0)
'a.b.c'
>>> regex.match(r"(?:moo ow dog cat){d}", "moo cow house car").group(0)
'moo c'
>>> regex.match(r"(?:moo ow dog cat){d}", "moo cow house car",
... regex.ENHANCEMATCH).group(0)
...
'moo c'
>>> # ^^ the 'c' above is not what we want in the output. As you can see,
>>> # the 'fuzzy' matching is a bit different from partial matching.
>>>
>>> regex_script = """
... for t in targets:
... for e in exprs:
... m = regex.match(rf"(?:{e}){{d}}", t)
... """
>>>
>>> cprof.run(regex_script)
57912 function calls (57835 primitive calls) in 0.180 seconds
...
>>> regex_script = """
... for t in targets:
... for e in exprs:
... m = regex.match(rf"(?:{e}){{d}}", t, flags=regex.ENHANCEMATCH)
... """
>>>
>>> cprof.run(regex_script)
57904 function calls (57827 primitive calls) in 0.298 seconds
性能比没有 regex.ENHANCEMATCH
标志的 partial_match()
解决方案好一点。但是,带有标志的速度较慢。
带有 regex.BESTMATCH
标志的正则表达式在行为上可能与 partial_match()
最相似,但它甚至更慢:
>>> regex_script = """
... for t in targets:
... for e in exprs:
... m = regex.match(rf"(?:{e}){{d}}", t, flags=regex.BESTMATCH)
... """
>>> cprof.run(regex_script)
57912 function calls (57835 primitive calls) in 0.338 seconds
regex
也有一个 partial=True
标志,但这似乎根本不像我们预期的那样起作用。
关于python - 部分正则表达式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36145045/
我有一个加号/减号按钮,希望用户不能选择超过 20 个但不知道如何让它工作。我尝试使用 min="1"max="5 属性,但它们不起作用。这是我的代码和一个 fiddle 链接。https://jsf
我正在尝试复制顶部底部图,如示例 here但它没有正确渲染(紫色系列有 +ve 和 -ve 值,绿色为负值)留下杂乱的人工制品。我也在努力创建一个玩具示例来复制这个问题,所以我希望尽管我缺乏数据,但有
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 6 年前。 社区去年审查了是
这个问题在这里已经有了答案: Adding two positive integers gives negative answer.Why? (4 个答案) 关闭 5 年前。 我遇到了一个奇怪的问题
有谁知道如何将字符串值类型 -4,5 或 5,4 转换为 double -4.5 或 5.4? 最佳答案 只需使用 Double.parseDouble(Locale, String); 糟糕,我很困
我正在尝试根据 TextBlob 分类插入一个仅包含“正”或“负”字符串的新数据框列:对于我的 df 的第一行,结果是 ( pos , 0.75, 0.2499999999999997)我想要' 正
我对 VBA 非常陌生,无法理解如何在一个循环中完成 2 个任务。我非常感谢您的帮助。 我已经能够根据第 3 列中的数据更改第 2 列中的数值,但我不明白如何将负值的字体更改为红色。 表格的大小每月都
欢迎, 我正在使用 jquery 通过 POST 发送表单。 这就是我获得值(value)的方式。 var mytext = $("#textareaid").val(); var dataStrin
double d = 0; // random decimal value with it's integral part within the range of Int32 and always p
我有这个字符串: var a='abc123#xyz123'; 我想构建 2 个正则表达式替换函数: 1) 用 '*' 替换所有确实有 future '#'的字符(不包括'#') 所以结果应该是这样的
我正在使用 DialogFragment。当用户从 Gmail 平板电脑应用程序的屏幕与下面示例图片中的编辑文本进行交互时,我希望正面和负面按钮保持在键盘上方。 在我的尝试中不起作用,这是我的 Dia
从组装艺术一书中,我复制了这句话: In the two’s complement system, the H.O. bit of a number is a sign bit. If the H.O
是否有更好更优雅的方法来实现下面的简单代码(diffYear、A 和 B 是数字): diffYear = yearA - yearB; if (diffYear == 0) { A = B
我正在设计一种语言,并尝试确定 true 应该是 0x01 还是 0xFF。显然,所有非零值都将转换为 true,但我正在尝试确定确切的内部表示。 每种选择的优点和缺点是什么? 最佳答案 没关系,只要
在我的 dialogfragment 类的 OnCreateDialog 中,我正在这样做: AlertDialog.Builder builder = new AlertDialog.Builder
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda usin
我偶然发现了一个奇怪的 NSDecimalNumber 行为:对于某些值,调用 integerValue、longValue、longLongValue 等,返回意想不到的值(value)。示例: l
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda using
我有这个正则表达式来测试用户输入是否有效: value.length === 0 || value === '-' || (!isNaN(parseFloat(value)) && /^-?\d+\.
我想用高斯混合模型拟合数据集,数据集包含大约 120k 个样本,每个样本有大约 130 个维度。当我使用 matlab 执行此操作时,我运行脚本(簇号为 1000): gm = fitgmdist(d
我是一名优秀的程序员,十分优秀!