【问题标题】:Operator precedence in regular expressions正则表达式中的运算符优先级
【发布时间】:2016-08-20 14:11:05
【问题描述】:

Oracle 正则表达式中不包含括号的默认运算符优先级是什么?

例如,给定

 H|ha+

它会被评估为H|h,然后连接到a,如((H|h)a),还是Hha 交替使用,如(H|(ha))

另外,+ 什么时候开始,等等?

【问题讨论】:

    标签: regex oracle oracle11g operator-precedence


    【解决方案1】:

    鉴于Oracle doc

    表 4-2 列出了支持在传递给 SQL 正则表达式函数和条件的正则表达式中使用的元字符列表。这些元字符符合 POSIX 标准;任何与标准的行为差异都会在“描述”列中注明。

    并查看该表中的 | 值:

    表达式 a|b 匹配字符 a 或字符 b。

    另外看看POSIX doc:

    运算符优先级 运算符的优先顺序如下:

    1. 与排序规则相关的括号符号 [==] [::] [..]

    2. 转义字符\

    3. 字符集(括号表达式)[]

    4. 分组()

    5. 单字符 ERE 重复 * + ? {m,n}

    6. 串联

    7. 锚定 ^$

    8. 交替 |

    我会说H|ha+(?:H|ha+) 相同。

    【讨论】:

    • ?: in (?: ...) 不是 Oracle 语法。
    • @mathguy 我同意,但我想表明它与(H|ha+) 不同,因为没有捕获组
    • 正如 Thomas 所展示的,交替(| 运算符)的优先级最低。使用 H|ha+ 的正则表达式搜索将首先尝试使用 H,并且只有在找不到匹配项时(在尝试了其他运算符指示的所有组合之后),作为最后的手段,它会再次尝试使用 ha+ 而不是 H。 + 是一元运算符,它只附加到 a 并且贪心适用。
    • 关于优先级的有趣问题:如果您有两个“交替”组,它们的评估顺序是什么?答案 - 第一个选择中的第一个选择与第二个选择中的所有选择一起尝试,如果没有找到任何匹配项,则尝试第一个选择中的第二个选择。 select regexp_substr('adibcd', '(a|b)(c|d)') from dual; 返回“ad”(另一个选择是“bc”,但在检查 ac 之后,正则表达式会在尝试 bc 之前检查 ad)。
    • @ThomasAyoub 点运算符 (".") 的优先级是什么?与其他通配符运算符相同吗?我似乎无法在任何地方找到答案。
    【解决方案2】:

    使用捕获组来展示评估顺序,正则表达式H|ha+等价于:

    (H|(h(a+)))
    

    这是因为优先级规则(如下所示)按照从最高优先级(编号最小)到最低优先级(编号最高)的顺序应用:

    • 规则 5 → (a+) +a 分组,因为此运算符适用于前面的单个字符、反向引用、组(Oracle 用语中的“标记的子表达式”) , 或括号表达式(字符类)。

    • 规则 6 → (h(a+)) h 然后与上一步中的组连接。

    • 规则 8 → (H|(h(a+))) H 然后与上一步中的组交替。



    9.4.8 of the POSIX docs for regular expressions 部分的优先级表(似乎没有官方的 Oracle 表):

    +---+----------------------------------------------------------+
    |   |             ERE Precedence (from high to low)            |
    +---+----------------------------------------------------------+
    | 1 | Collation-related bracket symbols | [==] [::] [..]       |
    | 2 | Escaped characters                | \<special character> |
    | 3 | Bracket expression                | []                   |
    | 4 | Grouping                          | ()                   |
    | 5 | Single-character-ERE duplication  | * + ? {m,n}          |
    | 6 | Concatenation                     |                      |
    | 7 | Anchoring                         | ^ $                  |
    | 8 | Alternation                       | |                    |
    +---+-----------------------------------+----------------------+
    

    上表适用于扩展正则表达式。有关基本正则表达式,请参阅9.3.7

    【讨论】:

    • Java 正则表达式是否支持排序规则符号?
    • @VictorGrazi Collat​​ion 符号在 POSIX 标准中定义,但遗憾的是它们并未得到广泛支持。 Java regex 包实现了一个“类 Perl”的正则表达式引擎,缺少一些功能(例如条件表达式和 cmets),但包括一些额外的功能(例如所有格量词和可变长度,但有限的后视断言) . Perl 和 Java 都不支持整理序列或字符等价。然而,Perl 确实 支持“正确的”POSIX 字符类,尽管 Java 只支持使用 \p 运算符(有一些注意事项)。
    • 如果我们将它包含在 ERE 优先表中,那么反向引用的位置在哪里?
    猜你喜欢
    • 2011-07-24
    • 2021-10-04
    • 2017-10-25
    • 2020-06-23
    • 2014-09-30
    • 2013-12-28
    • 2019-02-13
    • 2013-08-04
    • 2011-01-09
    相关资源
    最近更新 更多