【发布时间】:2016-08-20 14:11:05
【问题描述】:
Oracle 正则表达式中不包含括号的默认运算符优先级是什么?
例如,给定
H|ha+
它会被评估为H|h,然后连接到a,如((H|h)a),还是H 与ha 交替使用,如(H|(ha))?
另外,+ 什么时候开始,等等?
【问题讨论】:
标签: regex oracle oracle11g operator-precedence
Oracle 正则表达式中不包含括号的默认运算符优先级是什么?
例如,给定
H|ha+
它会被评估为H|h,然后连接到a,如((H|h)a),还是H 与ha 交替使用,如(H|(ha))?
另外,+ 什么时候开始,等等?
【问题讨论】:
标签: regex oracle oracle11g operator-precedence
鉴于Oracle doc:
表 4-2 列出了支持在传递给 SQL 正则表达式函数和条件的正则表达式中使用的元字符列表。这些元字符符合 POSIX 标准;任何与标准的行为差异都会在“描述”列中注明。
并查看该表中的 | 值:
表达式 a|b 匹配字符 a 或字符 b。
另外看看POSIX doc:
运算符优先级 运算符的优先顺序如下:
与排序规则相关的括号符号 [==] [::] [..]
转义字符\
字符集(括号表达式)[]
分组()
单字符 ERE 重复 * + ? {m,n}
串联
锚定 ^$
交替 |
我会说H|ha+ 与(?:H|ha+) 相同。
【讨论】:
(H|ha+) 不同,因为没有捕获组
select regexp_substr('adibcd', '(a|b)(c|d)') from dual; 返回“ad”(另一个选择是“bc”,但在检查 ac 之后,正则表达式会在尝试 bc 之前检查 ad)。
使用捕获组来展示评估顺序,正则表达式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。
【讨论】:
regex 包实现了一个“类 Perl”的正则表达式引擎,缺少一些功能(例如条件表达式和 cmets),但包括一些额外的功能(例如所有格量词和可变长度,但有限的后视断言) . Perl 和 Java 都不支持整理序列或字符等价。然而,Perl 确实 支持“正确的”POSIX 字符类,尽管 Java 只支持使用 \p 运算符(有一些注意事项)。