RFC 9485 I-Regexp October 2023
Bormann & Bray Standards Track [Page]
溪流:
互联网工程任务组 (IETF)
RFC:
9485
类别:
标准轨道
发表:
国际刊号:
2070-1721
作者:
C·博尔曼
不来梅 TZI 大学
T·布雷
文本性

RFC 9485

I-Regexp:可互操作的正则表达式格式

摘要

本文档指定了 I-Regexp,这是一种范围有限的正则表达式,其目标是跨许多不同的正则表达式库进行互操作。

本备忘录的状态

这是一份互联网标准跟踪文档。

本文档是互联网工程任务组 (IETF) 的产品。 它代表了IETF社区的共识。 它已接受公众审查,并已被互联网工程指导小组 (IESG) 批准发布。 有关互联网标准的更多信息,请参阅 RFC 7841 第 2 节。

有关本文档当前状态、任何勘误表以及如何提供反馈的信息,请访问 https://www.rfc-editor.org/info/rfc9485

目录

1. 简介

本规范描述了一种可互操作的正则表达式(缩写为“regexp”)风格,I-Regexp。

I-Regexp 不提供高级正则表达式功能,例如捕获组、前瞻或反向引用。 它仅支持布尔匹配功能,即测试给定的正则表达式是否与给定的文本片段匹配。

I-Regexp 支持整个 Unicode 字符库(Unicode 标量值); I-Regexp 字符串本身以及它们匹配的字符串都是 Unicode 标量值序列(通常以 UTF-8 编码形式 [STD63] 表示以进行交换)。

I-Regexp 是 XML 架构定义 (XSD) 正则表达式 [XSD-2] 的子集。

本文档包含有关转换 I-Regexp 以便与多种众所周知的正则表达式习惯用法一起使用的指南。

I-Regexp 的开发是由 JSONPath 工作组 (WG) 的工作推动的。 工作组希望在其规范 [JSONPATH-BASE] 中包含对在 JSONPath 过滤器中使用正则表达式的支持,但无法找到有用的正则表达式规范可以在流行的库之间进行互操作。

1.1. 术语

本文档使用缩写“regexp”来表示编程中通常所说的“正则表达式”。 术语“I-Regexp”用作名词,表示符合本规范要求的字符串(Unicode 标量值的序列);复数是“I-Regexps”。

本规范使用 Unicode 术语; [UNICODE-GLOSSARY] 提供了一个很好的切入点。

关键字“必须”、“不得”、“必需”、“应当”、“不应"、"应该"、"不应"、"推荐"、"不推荐本文档中的“”、“可以”和“可选0>”应按照 BCP 14 [RFC2119 中的描述进行解释t12>]1> [RFC81744>]3> 当且仅当它们全部大写出现时,如此处所示。¶5>

本文档中的语法规则应解释为 ABNF,如 [RFC5234][RFC7405] 中所述>,其中 [RFC5234] 的第 2.3 节 的“字符”是 Unicode 标量值。

2. 目标

I-Regexps 应该能够处理数据模型规范或查询语言表达式中需要匹配正则表达式的绝大多数实际情况。

在撰写本文时,本文档的编辑对最近发布的 RFC 中使用的正则表达式语法进行了调查。 在那里找到的所有示例都应该由 I-Regexps 涵盖,无论是在语法上还是在其预期语义上。 例外情况是使用多字符转义,第 5 节中提供了解决方法指南。

3. I-正则表达式语法

I-Regexp 必须符合图 1 中的 ABNF 规范。

i-regexp = branch *( "|" branch )
branch = *piece
piece = atom [ quantifier ]
quantifier = ( "*" / "+" / "?" ) / range-quantifier
range-quantifier = "{" QuantExact [ "," [ QuantExact ] ] "}"
QuantExact = 1*%x30-39 ; '0'-'9'

atom = NormalChar / charClass / ( "(" i-regexp ")" )
NormalChar = ( %x00-27 / "," / "-" / %x2F-3E ; '/'-'>'
 / %x40-5A ; '@'-'Z'
 / %x5E-7A ; '^'-'z'
 / %x7E-D7FF ; skip surrogate code points
 / %xE000-10FFFF )
charClass = "." / SingleCharEsc / charClassEsc / charClassExpr
SingleCharEsc = "\" ( %x28-2B ; '('-'+'
 / "-" / "." / "?" / %x5B-5E ; '['-'^'
 / %s"n" / %s"r" / %s"t" / %x7B-7D ; '{'-'}'
 )
charClassEsc = catEsc / complEsc
charClassExpr = "[" [ "^" ] ( "-" / CCE1 ) *CCE1 [ "-" ] "]"
CCE1 = ( CCchar [ "-" CCchar ] ) / charClassEsc
CCchar = ( %x00-2C / %x2E-5A ; '.'-'Z'
 / %x5E-D7FF ; skip surrogate code points
 / %xE000-10FFFF ) / SingleCharEsc
catEsc = %s"\p{" charProp "}"
complEsc = %s"\P{" charProp "}"
charProp = IsCategory
IsCategory = Letters / Marks / Numbers / Punctuation / Separators /
    Symbols / Others
Letters = %s"L" [ ( %s"l" / %s"m" / %s"o" / %s"t" / %s"u" ) ]
Marks = %s"M" [ ( %s"c" / %s"e" / %s"n" ) ]
Numbers = %s"N" [ ( %s"d" / %s"l" / %s"o" ) ]
Punctuation = %s"P" [ ( %x63-66 ; 'c'-'f'
 / %s"i" / %s"o" / %s"s" ) ]
Separators = %s"Z" [ ( %s"l" / %s"p" / %s"s" ) ]
Symbols = %s"S" [ ( %s"c" / %s"k" / %s"m" / %s"o" ) ]
Others = %s"C" [ ( %s"c" / %s"f" / %s"n" / %s"o" ) ]
图 1:ABNF 中的 I-Regexp 语法

作为附加限制,charClassExpr 不允许匹配 [^],根据此语法,它将解析为包含单个字符 的正字符类^.

这本质上是一个 XSD 正则表达式,没有:

I-Regexp 实现必须是这个有限子集的完整实现。 特别是,需要完全支持本规范中定义的 Unicode 功能。 实现:

3.1. 检查实施

检查 I-Regexp 实现是一种检查提供的正则表达式是否符合本规范并报告任何问题的实现。 检查实现可以让用户确信他们没有意外插入不可互操作的语法,因此推荐进行检查。 对于通过简单步骤(例如执行第 5 节 中讨论的映射操作)将 I-Regexp 映射到另一个 regexp 库的省力实现,可以对此规则进行例外处理。 在这里,进行全面检查所需的工作可能会使其余的实施工作相形见绌。 实现应该记录它们是否正在检查。

使用 I-Regexp 的规范可能想要定义在什么情况下它们的实现可以与非检查 I-Regexp 实现一起工作,以及何时需要全面检查,可能是在定义自己的实现类的过程中。

4. I-正则表达式语义

此语法是 [XSD-2] 语法的子集。 解释 I-Regexps 必须 的实现会产生 [XSD-2] 中指定的布尔结果。 (另请参阅第 5.2 节。)

5. 将 I-Regexp 映射到 Regexp 方言

本节中的材料不是规范性的;它为想要在其他正则表达式方言上下文中使用 I-Regexps 的开发人员提供指导。

5.1. 多字符转义

I-Regexp 不支持常见的多字符转义 (MCE) 和围绕它们构建的字符类。 这些通常可以替换,如表 1 中的示例所示。

Table 1: Example Substitutes for Multi-Character Escapes
MCE/class: Replace with:
\S [^ \t\n\r]
[\S ] [^\t\n\r]
\d [0-9]

请注意,XSD 正则表达式中 \d 的语义是 \p{Nd} 的语义;但是,这将包括各种书写系统中作为数字的所有 Unicode 字符,这几乎肯定不是 IETF 出版物所要求的。

构造 \p{IsBasicLatin} 本质上是对旧版 ASCII 的引用;可以用字符类 [\u0000-\u007f] 替换。

5.2. XSD 正则表达式

任何 I-Regexp 也是 XSD 正则表达式 [XSD-2],因此映射是一个恒等函数。

请注意,[XSD-2] 的一些勘误表已在 [XSD-1.1-2] 中修复;因此,它也包含在规范性参考文献(第9.1节)中。 XSD 1.1 的实现不如 XSD 1.0 广泛,XSD 1.0 的实现可能包含这些错误修复;就本规范的意图和目的而言,XSD 1.0 正则表达式的实现等同于 XSD 1.1 正则表达式的实现。

5.3. ECMAScript 正则表达式

对 I-Regexp 执行以下步骤以获取 ECMAScript 正则表达式 [ECMA-262]:

  • 对于字符类之外的任何未转义点 (.)(charClass 生成的第一个替代方案),将点替换为 [^\n\r] .
  • 将结果封装在 ^(?:)$ 中。

ECMAScript 正则表达式将被解释为 Unicode 模式(“u”标志;请参阅 [ECMA-262] 的第 21.2.2 节“模式语义”)。

请注意,如果需要正则表达式文字,则实际的正则表达式需要括在 / 中。

5.4. PCRE、RE2 和 Ruby 正则表达式

要获取 Perl 兼容正则表达式 (PCRE) [PCRE2] 中的有效正则表达式,Go 编程语言的 RE2 正则表达式库 [RE2 ] 和 Ruby 编程语言,执行与第 5.3 节中相同的步骤,除了最后一步是:

  • 将正则表达式括在 \A(?:)\z 中。

6. 动机和背景

虽然正则表达式最初旨在描述支持布尔匹配函数的形式语言,但它们已通过支持提取和替换匹配文本的任意部分的解析函数得到增强。 随着功能的增加,解析正则表达式库变得更容易出现错误和令人惊讶的性能下降,控制提交处理的正则表达式的攻击者可以在拒绝服务攻击中利用这些错误和性能下降。 I-Regexp 旨在提供互操作性并且不易受到此类攻击,但其唯一功能是提供关于字符序列是否与正则表达式匹配的布尔响应。

6.1. 实现 I-Regexp

XSD 正则表达式相对容易实现或映射到广泛实现的解析正则表达式方言,但有以下值得注意的例外:

  • 字符类减法。 在许多规范中,这是一个非常有用的功能,但不幸的是,解析正则表达式方言大多没有它。 因此,它在 I-Regexp 中被省略。
  • 多字符转义。 \d\w\s 及其大写补码类在正则表达式风格之间表现出大量差异。 因此,它们从 I-Regexp 中被省略。
  • 并非所有正则表达式实现都支持访问能够执行 \p{Nd} 等构造的 Unicode 表,尽管 \p/\P 功能一般来说,现在已相当广泛地可用。 虽然原则上可以将它们转换为字符类匹配,但这也需要访问这些表。 因此,严格受限环境中的正则表达式库可能无法支持 I-Regexp 一致性。

7. IANA 注意事项

本文档没有 IANA 操作。

8. 安全注意事项

虽然技术上超出了本规范的范围,但 RFC 3629 [STD63 的 10 部分(“安全注意事项”) ] 适用于实现。 Particular note needs to be taken of the last paragraph of Section 3 ("UTF-8 definition" ) of RFC 3629 [STD63]; an I-Regexp implementation may need to mitigate limitations of the platform implementation in this regard.

正如第 6 节中所讨论的,更复杂的正则表达式库可能包含可利用的错误,这可能导致崩溃和远程代码执行。 There is also the problem that such libraries often have performance characteristics that are hard to predict, leading to attacks that overload an implementation by matching against an expensive attacker-controlled regexp.

I-Regexp 的设计允许以能够抵御这两种威胁的方式实施;需要在整个实施工作中实现这一目标。 非检查实现(参见第 3.1 节)可能会暴露其使用的任何正则表达式引擎的安全限制,如果该引擎在构建时考虑到了安全性(例如,[RE2])。 无论如何,检查实现仍然是推荐

专门实现 I-Regexp 子集的实现可以谨慎地设计为通常在输入中的线性时间和空间中运行,并检测何时不会出现这种情况(见下文)。

现有的正则表达式引擎应该能够轻松处理大多数 I-Regexp(在第 5 节中讨论的调整之后),但可能会为某些类型的 I-Regexp 消耗过多的资源或完全拒绝它们,因为它们无法保证高效执行。 (请注意,在这些情况下,同一正则表达式库的不同版本可能或多或少容易受到过度资源消耗的影响。)

具体来说,范围量词(如a{2,4})给现有的和以 I-Regexp 为中心的实现带来了特殊的挑战。 因此,实现可能会限制范围量词的可组合性(不允许嵌套范围量词,例如 (a{2,4}){2,4})或范围(不允许非常大的范围,例如 a{ 20,200000}),或者检测并拒绝由范围量词引起的任何过度资源消耗。

在这些情况下,用于评估来自不受信任来源的正则表达式的 I-Regexp 实现需要具有鲁棒性。 鼓励实施者使用现有的正则表达式库:

9. 参考文献

9.1. 规范性参考文献

[RFC2119]
布拉德纳,S.“RFC 中用于指示需求级别的关键字”BCP 14RFC 2119DOI 10.17487/RFC2119 t3>、<https://www.rfc-editor.org/info/rfc2119>
[RFC5234]
克罗克,D.,埃德。 P。 Overell“语法规范的增强 BNF:ABNF”STD 68RFC 5234DOI 10.17487/RFC5234 <https://www.rfc-editor.org/info/rfc5234>
[RFC7405]
基济瓦特,P.“ABNF 中区分大小写的字符串支持”RFC 7405DOI 10.17487/RFC7405<https://www.rfc-editor.org/info/rfc7405>
[RFC8174]
莱巴,B.“RFC 2119 关键字中大写与小写的歧义”BCP 14RFC 8174DOI 10.17487/RFC8174<https://www.rfc-editor.org/info/rfc8174>
[XSD-1.1-2]
彼得森,D.,埃德。, 高,S.,埃德。, 马尔霍特拉,A.,埃德。, Sperberg-McQueen,C.M.,编者。, 汤普森,H.,埃德。, 和 P.拜伦,埃德。“W3C XML 架构定义语言 (XSD) 1.1 第 2 部分:数据类型”W3C REC REC-xmlschema11-2-20120405W3C REC-xmlschema11-2 -20120405<https://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/>
[XSD-2]
拜伦,P.,埃德。 A.马尔霍特拉,埃德。“XML 架构第 2 部分:数据类型第二版”W3C REC-xmlschema-2-20041028W3C REC-xmlschema-2-20041028<https://www.w3.org/TR/2004/REC-xmlschema-2-20041028/>

9.2. 信息参考

[ECMA-262]
Ecma International“ECMAScript 2020 语言规范”标准 ECMA-262 第 11 版<https://www.ecma-international.org/wp-content/uploads/ECMA-262.pdf>
[JSONPATH-BASE]
戈斯纳,S.,埃德。, 诺明顿,G.,埃德。, 和 C.博尔曼,埃德。, “JSONPath:JSON 查询表达式”,正在进行中,Internet-Draft,draft-ietf-jsonpath-base-20,,<https://datatracker.ietf.org/doc/html/draft-ietf-jsonpath-base-20>
[PCRE2]
“Perl 兼容正则表达式(修订版 API:PCRE2)”<http://pcre.org/current/doc/html/>
[RE2]
“RE2 是一种快速、安全、线程友好的替代方案,可替代 PCRE、Perl 和 Python 中使用的回溯正则表达式引擎。 它是一个 C++ 库。”提交 73031bb,<https://github.com/google/re2>
[RFC7493]
布雷,T.,埃德。“I-JSON 消息格式”RFC 7493DOI 10.17487/RFC7493<https://www.rfc-editor.org/info/rfc7493>
[性病63]
耶尔戈,F.“UTF-8,ISO 10646 的一种转换格式”STD 63RFC 3629
<https://www.rfc-editor.org/info/std63>
[UNICODE-词汇表]
统一码公司“Unicode 术语词汇表”<https://unicode.org/glossary/>

致谢

IETF JSONPATH WG 中关于是否将 regexp 机制纳入 JSONPath 查询表达式规范的讨论以及之前关于 YANG pattern 和简洁数据定义语言 (CDDL) .regexp 的讨论特性激发了此规范。

此规范的基本方法受到“I-JSON 消息格式”的启发[RFC7493]

作者地址

卡斯滕·鲍曼
不来梅 TZI 大学
邮政 330440
D-28359 不来梅
德国
电话: +49-421-218-63921
蒂姆·布雷
文本性
加拿大