分支重设群组分支重设群组分支重设群组分支重设群组
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2024年3月5日
类别
  • 正则表达式
标签
分支重设群组
  • 简
  • 繁
  • En
关于正则表达式 » 正则表达式教程 » 分支重设群组

正则表达式教程
简介
目录
特殊字符
不可打印字符
正则表达式引擎内部结构
字符类别
字符类别减法
字符类别交集
简写字符类别
点
锚点
字词边界
交替
选用项目
重复
群组和截取
反向引用
反向引用,第 2 部分
命名组
相对反向引用
分支重设群组
自由间距和注解
Unicode
模式修改器
原子组
独占量词
前瞻和后顾
环顾,第 2 部分
将文本保留在比对之外
条件
平衡组
递归
子常式
无限递归
递归和量词
递归和截取
递归和反向引用
递归和回溯
POSIX 方括号表达式
零长度比对
继续比对
本网站的更多内容
简介
正则表达式快速入门
正则表达式教程
替换字符串教程
应用程序和语言
正则表达式范例
正则表达式参考
替换字符串参考

分支重设群组

Perl 5.10 引进了一项新的正则表达式功能,称为分支重设群组。PCRE 7.2 及更新版本也支持此功能,还有像 PHP、Delphi 和 R 等基于 PCRE 的正则表达式函数的语言。 Boost 在 1.42 版中将其加入 ECMAScript 语法。

交替在分支重置群组内部共享相同的捕获组。语法为 (?|正则表达式),其中 (?| 打开群组,而 正则表达式 为任何正则表达式。如果您未在分支重置群组内部使用任何交替或捕获组,则其特殊功能不会发挥作用。它随后会作为 非捕获组 运作。

正则表达式 (?|(a)|(b)|(c)) 包含一个具有三个交替选项的分支重置群组。此正则表达式会比对 a、b 或 c。正则表达式只有一个编号为 1 的捕获组,由所有三个交替选项共享。比对后,$1 会包含 a、b 或 c。

将其与缺乏分支重置群组的正则表达式 (a)|(b)|(c) 进行比较。此正则表达式也会比对 a、b 或 c。但它有三个捕获组。比对后,$1 会包含 a 或什么都不包含,$2 会包含 b 或什么都不包含,而 $3 会包含 c 或什么都不包含。

反向引用在分支重置群组内部的捕获组会依照您的预期运作。 (?|(a)|(b)|(c))\1 会比对 aa、bb 或 cc。由于分支重置群组内部只有一个交替选项可以比对,因此参与比对的交替选项会决定捕获组保存的文本,进而决定反向引用比对的文本。

分支重设群组中的替代方案不需要有相同数量的捕获组。 (?|abc|(d)(e)(f)|g(h)i) 有三个捕获组。当此正则表达式符合 abc 时,所有三个群组都是空的。当 def 符合时,$1 包含 d,$2 包含 e,$3 包含 f。当 ghi 符合时,$1 包含 h,而其他两个是空的。

您可以在分支重置群组之前和之后使用捕获组。分支重置群组之前的群组会依通常方式编号。分支重置群组中的群组会从分支重置群组之前的群组继续编号,每个选项都会重设编号。分支重置群组之后的群组会从具有最多群组的选项继续编号,即使那不是最后一个选项。因此 (x)(?|abc|(d)(e)(f)|g(h)i)(y) 定义了五个捕获组。 (x) 是群组 1,(d) 和 (h) 是群组 2,(e) 是群组 3,(f) 是群组 4,以及 (y) 是群组 5。

分支重置群组中的命名捕获组

您可以在分支重置群组中使用 命名捕获组。如果您这样做,您应该对将取得相同编号的群组使用相同的名称。否则,您会在 Perl 或 Boost 中得到不想要的行为。PCRE 仅从版本 8.00 开始可靠地支持分支重置群组中的命名组。这表示 Delphi 仅从 XE7 开始支持,而 PHP 则从版本 5.2.14 开始支持。

(?'before'x)(?|abc|(?'left'd)(?'middle'e)(?'right'f)|g(?'left'h)i)(?'after'y) 与前一个正则表达式相同。它将五个群组命名为「before」、「left」、「middle」、「right」和「after」。请注意,由于第 3 个选项只有一个捕获组,因此那必须是其他选项中第一个群组的名称。

如果您省略某些替代方案中的名称,群组仍会与其他替代方案共用名称。在正则表达式 (?'before'x)(?|abc|(?'left'd)(?'middle'e)(?'right'f)|g(h)i)(?'after'y) 中,群组 (h) 仍命名为「left」,因为分支重设群组使其共用 (?'left'd) 的名称和编号。

在 Perl、PCRE 和 Boost 中,当您希望不同替代方案中的群组拥有相同名称时,最好使用分支重设群组。这是 Perl、PCRE 和 Boost 中确保具有相同名称的群组实际上是同一个群组的唯一方法。

具有准确天数的日期和月份

现在是更实用的范例。这两个正则表达式会比对 m/d 或 mm/dd 格式的日期。它们会排除无效日期,例如 2/31。

^(?:(0?[13578]|1[02])/(3[01]|[12][0-9]|0?[1-9]) # 31 天
 
|  (0?[469]|11)/(30|[12][0-9]|0?[1-9])         # 30 天
 
|  (0?2)/([12][0-9]|0?[1-9])                   # 29 天
 
)$

第一个版本使用 非捕获组 (?:…) 来群组选项。它有六个独立的捕获组。 $1 和 $2 保留 31 天月份的月份和日期。 $3 和 $4 保留 30 天月份的月份和日期。 $5 和 $6 仅用于二月。

^(?|(0?[13578]|1[02])/(3[01]|[12][0-9]|0?[1-9]) # 31 天
 
|  (0?[469]|11)/(30|[12][0-9]|0?[1-9])         # 30 天
 
|  (0?2)/([12][0-9]|0?[1-9])                   # 29 天
 
)$

第二个版本使用分支重置群组 (?|…) 来群组备选项并合并其捕获组。这两个正则表达式的第 4 个字符是唯一的不同。现在只有两个捕获组。它们在树状备选项之间共用。当找到一个符合项时,$1 永远包含月份,而 2 永远包含日期,与月份中的天数无关。

分支重設群組
  • 简
  • 繁
  • En
關於正規表示式 » 正規表示式教學 » 分支重設群組

正規表示式教學
簡介
目錄
特殊字元
不可列印字元
正規表示式引擎內部結構
字元類別
字元類別減法
字元類別交集
簡寫字元類別
點
錨點
字詞邊界
交替
選用項目
重複
群組和擷取
反向參照
反向參照,第 2 部分
命名群組
相對反向參照
分支重設群組
自由間距和註解
Unicode
模式修改器
原子群組
獨佔量詞
前瞻和後顧
環顧,第 2 部分
將文字保留在比對之外
條件
平衡群組
遞迴
子常式
無限遞迴
遞迴和量詞
遞迴和擷取
遞迴和反向參照
遞迴和回溯
POSIX 方括號表示式
零長度比對
繼續比對
本網站的更多內容
簡介
正規表示式快速入門
正規表示式教學
替換字串教學
應用程式和語言
正規表示式範例
正規表示式參考
替換字串參考

分支重設群組

Perl 5.10 引進了一項新的正規表示式功能,稱為分支重設群組。PCRE 7.2 及更新版本也支援此功能,還有像 PHP、Delphi 和 R 等基於 PCRE 的正規表示式函數的語言。 Boost 在 1.42 版中將其加入 ECMAScript 語法。

交替在分支重置群組內部共享相同的擷取群組。語法為 (?|正規表示法),其中 (?| 開啟群組,而 正規表示法 為任何正規表示法。如果您未在分支重置群組內部使用任何交替或擷取群組,則其特殊功能不會發揮作用。它隨後會作為 非擷取群組 運作。

正規表示法 (?|(a)|(b)|(c)) 包含一個具有三個交替選項的分支重置群組。此正規表示法會比對 a、b 或 c。正規表示法只有一個編號為 1 的擷取群組,由所有三個交替選項共享。比對後,$1 會包含 a、b 或 c。

將其與缺乏分支重置群組的正規表示法 (a)|(b)|(c) 進行比較。此正規表示法也會比對 a、b 或 c。但它有三個擷取群組。比對後,$1 會包含 a 或什麼都不包含,$2 會包含 b 或什麼都不包含,而 $3 會包含 c 或什麼都不包含。

反向參照在分支重置群組內部的擷取群組會依照您的預期運作。 (?|(a)|(b)|(c))\1 會比對 aa、bb 或 cc。由於分支重置群組內部只有一個交替選項可以比對,因此參與比對的交替選項會決定擷取群組儲存的文字,進而決定反向參照比對的文字。

分支重設群組中的替代方案不需要有相同數量的擷取群組。 (?|abc|(d)(e)(f)|g(h)i) 有三個擷取群組。當此正規表示法符合 abc 時,所有三個群組都是空的。當 def 符合時,$1 包含 d,$2 包含 e,$3 包含 f。當 ghi 符合時,$1 包含 h,而其他兩個是空的。

您可以在分支重置群組之前和之後使用擷取群組。分支重置群組之前的群組會依通常方式編號。分支重置群組中的群組會從分支重置群組之前的群組繼續編號,每個選項都會重設編號。分支重置群組之後的群組會從具有最多群組的選項繼續編號,即使那不是最後一個選項。因此 (x)(?|abc|(d)(e)(f)|g(h)i)(y) 定義了五個擷取群組。 (x) 是群組 1,(d) 和 (h) 是群組 2,(e) 是群組 3,(f) 是群組 4,以及 (y) 是群組 5。

分支重置群組中的命名擷取群組

您可以在分支重置群組中使用 命名擷取群組。如果您這樣做,您應該對將取得相同編號的群組使用相同的名稱。否則,您會在 Perl 或 Boost 中得到不想要的行為。PCRE 僅從版本 8.00 開始可靠地支援分支重置群組中的命名群組。這表示 Delphi 僅從 XE7 開始支援,而 PHP 則從版本 5.2.14 開始支援。

(?'before'x)(?|abc|(?'left'd)(?'middle'e)(?'right'f)|g(?'left'h)i)(?'after'y) 與前一個正規表示式相同。它將五個群組命名為「before」、「left」、「middle」、「right」和「after」。請注意,由於第 3 個選項只有一個擷取群組,因此那必須是其他選項中第一個群組的名稱。

如果您省略某些替代方案中的名稱,群組仍會與其他替代方案共用名稱。在正規表示式 (?'before'x)(?|abc|(?'left'd)(?'middle'e)(?'right'f)|g(h)i)(?'after'y) 中,群組 (h) 仍命名為「left」,因為分支重設群組使其共用 (?'left'd) 的名稱和編號。

在 Perl、PCRE 和 Boost 中,當您希望不同替代方案中的群組擁有相同名稱時,最好使用分支重設群組。這是 Perl、PCRE 和 Boost 中確保具有相同名稱的群組實際上是同一個群組的唯一方法。

具有準確天數的日期和月份

現在是更實用的範例。這兩個正規表示式會比對 m/d 或 mm/dd 格式的日期。它們會排除無效日期,例如 2/31。

^(?:(0?[13578]|1[02])/(3[01]|[12][0-9]|0?[1-9]) # 31 天
 
|  (0?[469]|11)/(30|[12][0-9]|0?[1-9])         # 30 天
 
|  (0?2)/([12][0-9]|0?[1-9])                   # 29 天
 
)$

第一個版本使用 非擷取群組 (?:…) 來群組選項。它有六個獨立的擷取群組。 $1 和 $2 保留 31 天月份的月份和日期。 $3 和 $4 保留 30 天月份的月份和日期。 $5 和 $6 僅用於二月。

^(?|(0?[13578]|1[02])/(3[01]|[12][0-9]|0?[1-9]) # 31 天
 
|  (0?[469]|11)/(30|[12][0-9]|0?[1-9])         # 30 天
 
|  (0?2)/([12][0-9]|0?[1-9])                   # 29 天
 
)$

第二個版本使用分支重置群組 (?|…) 來群組備選項並合併其擷取群組。這兩個正規表示式的第 4 個字元是唯一的不同。現在只有兩個擷取群組。它們在樹狀備選項之間共用。當找到一個符合項時,$1 永遠包含月份,而 2 永遠包含日期,與月份中的天數無關。

Branch Reset Groups
  • 简
  • 繁
  • En
About Regular Expressions » Regular Expressions Tutorial » Branch Reset Groups

Regex Tutorial
Introduction
Table of Contents
Special Characters
Non-Printable Characters
Regex Engine Internals
Character Classes
Character Class Subtraction
Character Class Intersection
Shorthand Character Classes
Dot
Anchors
Word Boundaries
Alternation
Optional Items
Repetition
Grouping & Capturing
Backreferences
Backreferences, part 2
Named Groups
Relative Backreferences
Branch Reset Groups
Free-Spacing & Comments
Unicode
Mode Modifiers
Atomic Grouping
Possessive Quantifiers
Lookahead & Lookbehind
Lookaround, part 2
Keep Text out of The Match
Conditionals
Balancing Groups
Recursion
Subroutines
Infinite Recursion
Recursion & Quantifiers
Recursion & Capturing
Recursion & Backreferences
Recursion & Backtracking
POSIX Bracket Expressions
Zero-Length Matches
Continuing Matches
More on This Site
Introduction
Regular Expressions Quick Start
Regular Expressions Tutorial
Replacement Strings Tutorial
Applications and Languages
Regular Expressions Examples
Regular Expressions Reference
Replacement Strings Reference

Branch Reset Groups

Perl 5.10 introduced a new regular expression feature called a branch reset group. PCRE 7.2 and later also support this, as do languages like PHP, Delphi, and R that have regex functions based on PCRE. Boost added them to its ECMAScript grammar in version 1.42.

Alternatives inside a branch reset group share the same capturing groups. The syntax is (?|regex) where (?| opens the group and regex is any regular expression. If you don’t use any alternation or capturing groups inside the branch reset group, then its special function doesn’t come into play. It then acts as a non-capturing group.

The regex (?|(a)|(b)|(c)) consists of a single branch reset group with three alternatives. This regex matches either a, b, or c. The regex has only a single capturing group with number 1 that is shared by all three alternatives. After the match, $1 holds a, b, or c.

Compare this with the regex (a)|(b)|(c) that lacks the branch reset group. This regex also matches a, b, or c. But it has three capturing groups. After the match, $1 holds a or nothing at all, $2 holds b or nothing at all, while $3 holds c or nothing at all.

Backreferences to capturing groups inside branch reset groups work like you’d expect. (?|(a)|(b)|(c))\1 matches aa, bb, or cc. Since only one of the alternatives inside the branch reset group can match, the alternative that participates in the match determines the text stored by the capturing group and thus the text matched by the backreference.

The alternatives in the branch reset group don’t need to have the same number of capturing groups. (?|abc|(d)(e)(f)|g(h)i) has three capturing groups. When this regex matches abc, all three groups are empty. When def is matched, $1 holds d, $2 holds e and $3 holds f. When ghi is matched, $1 holds h while the other two are empty.

You can have capturing groups before and after the branch reset group. Groups before the branch reset group are numbered as usual. Groups in the branch reset group are numbered continued from the groups before the branch reset group, which each alternative resetting the number. Groups after the branch reset group are numbered continued from the alternative with the most groups, even if that is not the last alternative. So (x)(?|abc|(d)(e)(f)|g(h)i)(y) defines five capturing groups. (x) is group 1, (d) and (h) are group 2, (e) is group 3, (f) is group 4, and (y) is group 5.

Named Capturing Groups in Branch Reset Groups

You can use named capturing groups inside branch reset groups. If you do, you should use the same names for the groups that will get the same numbers. Otherwise you’ll get undesirable behavior in Perl or Boost. PCRE only reliably supports named groups inside branch reset groups starting with version 8.00. This means Delphi only does so starting with XE7 and PHP starting with version 5.2.14.

(?'before'x)(?|abc|(?'left'd)(?'middle'e)(?'right'f)|g(?'left'h)i)(?'after'y) is the same as the previous regex. It names the five groups “before”, “left”, “middle”, “right”, and “after”. Notice that because the 3rd alternative has only one capturing group, that must be the name of the first group in the other alternatives.

If you omit the names in some alternatives, the groups will still share the names with the other alternatives. In the regex (?'before'x)(?|abc|(?'left'd)(?'middle'e)(?'right'f)|g(h)i)(?'after'y) the group (h) is still named “left” because the branch reset group makes it share the name and number of (?'left'd).

In Perl, PCRE, and Boost, it is best to use a branch reset group when you want groups in different alternatives to have the same name. That’s the only way in Perl, PCRE, and Boost to make sure that groups with the same name really are one and the same group.

Day and Month with Accurate Number of Days

It’s time for a more practical example. These two regular expressions match a date in m/d or mm/dd format. They exclude invalid dates such as 2/31.

^(?:(0?[13578]|1[02])/(3[01]|[12][0-9]|0?[1-9]) # 31 days
 
|  (0?[469]|11)/(30|[12][0-9]|0?[1-9])         # 30 days
 
|  (0?2)/([12][0-9]|0?[1-9])                   # 29 days
 
)$

The first version uses a non-capturing group (?:…) to group the alternatives. It has six separate capturing groups. $1 and $2 hold the month and the day for months with 31 days. $3 and $4 hold them for months with 30 days. $5 and $6 are only used for February.

^(?|(0?[13578]|1[02])/(3[01]|[12][0-9]|0?[1-9]) # 31 days
 
|  (0?[469]|11)/(30|[12][0-9]|0?[1-9])         # 30 days
 
|  (0?2)/([12][0-9]|0?[1-9])                   # 29 days
 
)$

The second version uses a branch reset group (?|…) to group the alternatives and merge their capturing groups. The 4th character is the only difference between these two regexes. Now there are only two capturing groups. These are shared between the three alternatives. When a match is found $1 always holds the month and 2 always holds the day, regardless of the number of days in the month.

©2015-2025 艾丽卡 support@alaica.com