【问题标题】:regular expressions, the meaning of curly braces正则表达式,大括号的含义
【发布时间】:2016-08-08 16:27:08
【问题描述】:

我目前正在编写一些 python 代码,它使用“re”python 包在给定的项目列表中搜索具有正则表达式模式的项目。

在查看代码时,我遇到了一些我无法理解的关于正则表达式的花括号的问题。

代码片段是这样的。

regex = re.search("mov .* ptr \[(?P<dst>([(rax)|(rbx)|(rcx)|(rdx)|(rsi)|(rdi)|(r9)|(r10)|(r11)|(r12)|(r13)|(r14)|(r15)]{3}))\], (?P<src>([(rax)|(rbx)|(rcx)|(rdx)|(rsi)|(rdi)|(r9)|(r10)|(r11)|(r12)|(r13)|(r14)|(r15)]{3}))$", f)

f 是给定的输入,看起来像这样。

regex变成1,我打印了f的内容,显示是这样的。

"mov qword ptr [rsi], rdi"

我无法理解的是正则表达式中的花括号,在本例中为“{3}”。 据我了解,只有一个数字“n”的花括号用于表示前面的表达式需要恰好出现“n”次才能匹配(在我的例子中是 3 次)。 (例如,ab{3} 将导致 abbb 匹配)

所以,如果这是正确的,我认为“(rax),(rbx),(rcx)等”之一需要恰好出现3次才能匹配,但关于上面显示的f的内容,事实并非如此。

所以我想知道我遗漏了哪一点以及如何理解上面正则表达式中的花括号。

【问题讨论】:

  • 文字/字符的重复次数
  • 你能提供一个输入到搜索方法中的测试字符串吗?
  • 这个正则表达式“有效”是由于错误使用了字符类。 [(rax)|(rbx)|(rcx)|(rdx)|(rsi)|(rdi)|(r9)|(r10)|(r11)|(r12)|(r13)|(r14)|(r15)] 只是匹配里面的一个字符。
  • 您可能希望将您的模式重写为mov .*? ptr \[(?P&lt;dst&gt;r(?:[abcd]x|[sd]i|9|1[012345]))\], (?P&lt;src&gt;r(?:[abcd]x|[sd]i|9|1[012345]))$

标签: python regex


【解决方案1】:

提供的正则表达式使用方括号不正确。括号表示一组字符,因此这些字符后面的{3} 表示这些字符中的三个字符的任意组合都将匹配。您可以在[] 下查看文档here

我相信正确的正则表达式应该是这样的:

regex = re.search(
    'mov .* ptr '
    '\[(?P<dst>(rax|rbx|rcx|rdx|rsi|rdi|r9|r10|r11|r12|r13|r14|r15))\], '
    '(?P<src>(rax|rbx|rcx|rdx|rsi|rdi|r9|r10|r11|r12|r13|r14|r15))$', f)

【讨论】:

    【解决方案2】:

    你所拥有的是一个虚假的正则表达式。它并没有完全按照写它的人的意图去做。

    为了证明这一点,我输入了一个无效的输入:

    $ python2
    ...
    >>> s = ("mov .* ptr \[(?P<dst>([(rax)|(rbx)|(rcx)|(rdx)|"
    ... "(rsi)|(rdi)|(r9)|(r10)|(r11)|(r12)|(r13)|(r14)|"
    ... "(r15)]{3}))\], (?P<src>([(rax)|(rbx)|(rcx)|(rdx)|"
    ... "(rsi)|(rdi)|(r9)|(r10)|(r11)|(r12)|(r13)|(r14)|(r15)]{3}))$")
    >>> import re
    >>> r2 = re.search(s, "mov qword ptr [r5i], rdi")
    >>> r2
    <_sre.SRE_Match object at 0x800684ca8>
    >>> r2.group('dst')
    'r5i'
    >>> r2 = re.search(s, "mov qword ptr [(5i], rdi")
    >>> r2.group('dst')
    '(5i'
    >>>
    

    很难说写这个表达式的人的想法是什么,以及他们是如何想出他们最终使用的东西的。不过,您是对的,{3} 的意思是“精确重复 3 次”。

    【讨论】:

    • 我猜正则表达式不是伪造的,但对于他们的用例来说已经足够好了,因为如果你在你的反汇编代码中使用[(5i],你就会在其他地方遇到问题。如果你手动编写代码,那么它无论如何都不会编译...
    • @RedX:“足够好”取决于它的用途。在任何情况下,它都不是一个非常明智的正则表达式。 Karin 的回答中的一个清晰而正确,Sebastian Proske 的评论中的一个简洁而正确。
    【解决方案3】:

    其他人已经正确回答了,我只是向您展示了一种可视化/测试您的正则表达式模式的方法。

    Debuggex Demo

    【讨论】:

    • 该图适用于来自Karin's answer更正 正则表达式。如果您包含原始的、损坏的正则表达式的图表以进行比较,将会更有帮助 - 不幸的是,该图像有一码宽 (literally!)。
    猜你喜欢
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多