PCRE2 开放原代码正则表达式程序库PCRE2 开放原代码正则表达式程序库PCRE2 开放原代码正则表达式程序库PCRE2 开放原代码正则表达式程序库
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2024年3月5日
类别
  • 正则表达式
标签
PCRE2 开放原代码正则表达式程序库
  • 简
  • 繁
  • En
关于正则表达式 » 正则表达式工具和实用程序 » PCRE2 开放原代码正则表达式程序库

正则表达式工具
grep
语言和程序库
Boost
Delphi
GNU (Linux)
Groovy
Java
JavaScript
.NET
PCRE (C/C++)
PCRE2 (C/C++)
Perl
PHP
POSIX
PowerShell
Python
R
Ruby
std::regex
Tcl
VBScript
Visual Basic 6
wxWidgets
XML Schema
Xojo
XQuery 和 XPath
XRegExp
数据库
MySQL
Oracle
PostgreSQL
本网站的更多内容
简介
正则表达式快速入门
正则表达式教程
替换字符串教程
应用程序和语言
正则表达式范例
正则表达式参考
替换字符串参考

PCRE2 开放原代码正则表达式程序库

PCRE2 是 Perl 兼容正则表达式的简称,版本 2。它是广受欢迎的 PCRE 程序库的后继版本。这两个都是由 Philip Hazel 以 C 编写的开放原代码程序库。

第一个 PCRE2 版本给予版本号码 10.00,以与先前的 PCRE 8.36 明确区分。PCRE 8.37 到 8.44 和任何未来的 PCRE 版本都仅限于修正错误。新功能只会添加到 PCRE2。如果您要进行新的开发项目,您应该考虑使用 PCRE2,而不是 PCRE。但是对于已经使用 PCRE 的现有项目,最好还是坚持使用 PCRE。从 PCRE 移转到 PCRE2 需要对您的原代码进行重大变更。这样做的唯一真正原因是使用新的搜索和取代功能。

PHP 7.3.0 从 PCRE 移转到 PCRE2,但没有使用新的 PCRE2 搜索和取代。它继续使用 PHP 本身的替换文本语法。

R 4.0.0 也将其 grep 及相关函数从 PCRE 移至 PCRE2。其 sub 及 gsub 函数持续使用 R 本身的替换文本语法。

PCRE2 10.00 至 10.34 及 PCRE 8.36 至 8.44 支持的正则表达式语法大致相同。因此,本网站上 正则表达式教程 中关于 PCRE(或特别是 PCRE 版本 8.36 至 8.44)的说明也适用于 PCRE2。PCRE2 仅在与 PCRE 不同的几个特定区域中被提及。

正则表达式语法有新的版本检查条件。该语法很像 检查命名反向引用的条件,但包含等号(以及捕获组名称中不允许的其他符号),使其在原始 PCRE 中成为语法错误。在所有版本的 PCRE2 中,(?(VERSION>=10.00)yes|no) 在字符串 yesno 中比对 yes。您可以对「yes」和「no」部分使用任何有效的正则表达式。如果版本检查成功,则会尝试「yes」部分。否则,会尝试「no」部分。这完全就像一个正常的条件,根据捕获组是否参与比对,来评估直线符号前或后的部分。

您可以使用 >= 检查最小版本,或使用 = 检查特定版本。 (?(VERSION=10.00)yes|no) 在 PCRE2 10.00 中比对 yes。它在 PCRE2 10.10 和所有后续版本中比对 no。省略次要版本号码与指定 .00 相同。因此,(?(VERSION>=10)yes|no) 在所有版本的 PCRE2 中比对 yes,但 (?(VERSION=10)yes|no) 仅在 PCRE2 10.00 中比对 yes。如果您指定次要版本号码,您应该在小数点后使用两个数字。从版本 10.21 开始,三个或更多数字会产生错误。版本 10.21 也变更了个位数数字的诠释,包括以零开头的数字。由于第一个版本是 10.00,第二个版本是 10.10,因此不需要检查个位数数字。如果您指定次要版本号码,您不能省略小数点。 (?(VERSION>=1000)yes|no) 检查版本 1000.00 或更高。

此版本检查条件主要适用于间接使用 PCRE2 的人,通过提供基于 PCRE2 的正则表达式支持或嵌入 PCRE2 但不公开其所有函数调用的应用程序或编程语言。它允许他们找出应用程序使用的 PCRE2 版本。如果您使用 PCRE2 C 函数库开发应用程序,则您应该使用函数调用来确定 PCRE2 版本。

char version[255];
pcre2_config(PCRE2_CONFIG_VERSION, version);

UTF-8、UTF-16 或 UTF-32

在原始的 PCRE 函数库中,UTF-16 和 UTF-32 支持是在后续版本中通过附加函数添加的,这些函数以 pcre16_ 和 pcre32_ 为前缀。在 PCRE2 中,所有函数都以 pcre2_ 为前缀,并以 _8、_16 或 _32 为后缀,以选取 8 比特、16 比特或 32 比特代码单位。如果您从原代码编译 PCRE2,您需要将 --enable-pcre2-16 和 --enable-pcre2-32 传递给 configure 脚本,以确保 _16 和 _32 函数可用。

8 比特、16 比特或 32 比特代码单位表示 PCRE2 会将您的字符串解释为由单字节字符、双字节字符或四字节字符组成。若要使用 UTF-8、UTF-16 或 UTF-32,您需要使用具有对应代码单位大小的函数,并将 PCRE2_UTF 选项传递给 pcre2_compile,以允许字符由多个代码单位组成。UTF-8 字符由 1 到 4 个字节组成。UTF-16 字符由 1 或 2 个字组成。

如果您想要在没有任何后缀的情况下调用 PCRE2 函数,如下所示,那么您需要将 PCRE2_CODE_UNIT_WIDTH 定义为 8、16 或 32,以使没有后缀的函数使用 8 比特、16 比特或 32 比特代码单位。在包含函数库之前运行此操作,如下所示

#define PCRE2_CODE_UNIT_WIDTH 8
#include "pcre2.h"

没有后缀的函数始终使用您定义的代码单位大小。具有后缀的函数仍然可用。因此,您的应用程序可以使用具有所有三种代码单位大小的正则表达式。但重要的是不要将它们混淆。如果需要将相同的正则表达式与 UTF-8 和 UTF-16 字符串比对,则您需要使用 pcre_compile_8 和 pcre_compile_16 编译它两次,然后使用对应的 pcre_match_8 和 pcre_match_16 函数使用已编译的正则表达式。

使用 PCRE2

使用 PCRE2 比使用 PCRE 稍微复杂一些。使用 PCRE2 时,您必须使用各种类型的内容传递某些编译或比对选项,例如换行处理。在 PCRE 中,这些选项可以在编译或比对时直接传递为选项比特。

在使用正则表达式之前,需要将其转换为二进位格式以提升效率。为此,只需调用 pcre2_compile(),并将正则表达式作为字符串传递。如果字符串以 null 结束,则可以将 PCRE2_ZERO_TERMINATED 传递为第二个参数。否则,请将长度传递为第二个参数中的代码单位。对于 UTF-8,这是以字节为单位的长度,而对于 UTF-16 或 UTF-32,这是以字节长度除以 2 或 4。第三个参数是一组选项,与二进位或结合。您应该包含 PCRE2_UTF 以获得适当的 UTF-8、UTF-16 或 UTF-32 支持。如果您省略它,您将获得纯 8 比特、或 UCS-2 或 UCS-4 字符处理。其他常见选项包括 PCRE2_CASELESS、PCRE2_DOTALL、PCRE2_MULTILINE 等。第四和第五个参数接收错误条件。最后一个参数是内容。除非您需要特殊换行处理,否则传递 NULL。当您完成正则表达式时,函数会传回指针至其配置的内存。您必须使用 pcre2_code_free() 释放此内存。

如果您需要非缺省换行处理,您需要调用 pcre2_compile_context_create(NULL) 来创建新的编译内容。然后调用 pcre2_set_newline() 传递该内容和选项之一,例如 PCRE2_NEWLINE_LF 或 PCRE2_NEWLINE_CRLF。然后将此内容作为最后一个参数传递至 pcre2_compile()。您可以对任意数量的正则表达式编译重复使用相同的内容。当您完成后,请调用 pcre2_compile_context_free()。请注意,在原始 PCRE 中,您可以将 PCRE_NEWLINE_LF 等直接传递至 pcre_compile()。这不适用于 PCRE2。如果您将 PCRE2_NEWLINE_LF 等传递至 pcre2_compile(),PCRE2 也不会抱怨。但这样做没有效果。您必须使用比对内容。

在使用已编译的正则表达式寻找字符串中的配对之前,您需要调用 pcre2_match_data_create_from_pattern() 来配置保存配对结果的内存。将已编译的正则表达式传递为第一个参数,并将 NULL 传递为第二个参数。此函数会传回已配置内存的指针。当您完成配对数据时,您必须使用 pcre2_match_data_free() 释放此内存。您可以重复使用相同的配对数据来多次调用 pcre2_match()。

若要寻找配对,请调用 pcre2_match() 并传递已编译的正则表达式、主旨字符串、整个字符串的长度、配对尝试必须开始的字符的偏移量、配对选项、配对数据对象的指针,以及 NULL 作为内容。长度和起始偏移量以代码单位表示,而非字符。当配对成功时,此函数会传回正数。PCRE2_ERROR_NOMATCH 表示未找到配对。任何其他非正回传值表示错误。可以使用 pcre2_get_error_message() 取得错误消息。

若要找出字符串的哪一部分配对,请调用 pcre2_get_ovector_pointer()。这会传回 PCRE2_SIZE 值数组的指针。您不需要释放此指针。当您调用 pcre2_match_data_free() 时,它将会失效。数组的长度是 pcre2_match() 传回的值。数组中的前两个值是整体配对的开始和结束。第二对是第一个捕获组的配对,依此类推。如果您的正则表达式有命名捕获组,请调用 pcre2_substring_number_from_name() 来取得群组号码。

如果您只想取得配对的文本,您可以使用便利函数,例如 pcre2_substring_copy_bynumber() 或 pcre2_substring_copy_byname()。传递捕获组的号码或名称,或传递零表示整体配对。使用 pcre2_substring_free() 释放结果。如果结果不需要以零终止,您可以使用 pcre2_substring_get_bynumber() 和 pcre2_substring_get_byname() 来取得原始主旨字符串中配对开始位置的指针。pcre2_substring_length_bynumber() 和 pcre2_substring_length_byname() 会提供配对的长度。

PCRE2 没有提供函数让您取得字符串中正则表达式的所有配对。它永远只会传回第一个配对。若要取得第二个配对,请再次调用 pcre2_match() 并传递 ovector[1](第一个配对的结束)作为第二个配对尝试的起始位置。如果第一个配对为零长度,请在传递给 pcre2_match() 的选项中包含 PCRE2_NOTEMPTY_ATSTART,以避免再次找到相同的零长度配对。这与在调用之前递增起始位置不同。使用 PCRE2_NOTEMPTY_ATSTART 传递前一个配对的结束可能会导致在相同位置找到非零长度的配对。

取代配对

PCRE 愿望清单中永远最大的项目可能是搜索和取代功能。PCRE2 终于实现了。取代字符串语法相当简单。不过,它与 Perl 不兼容。反向引用可以指定为 $group 或 ${group},其中「group」是群组的名称或编号。整体比对是群组编号 0。若要将文本美元符号添加至取代字符串,您需要重复输入。任何不属于有效反向引用的单一美元符号都是错误。与 Python 相似,但与 Perl 不同,PCRE2 将 不存在群组的反向引用 和 不参与群组的反向引用 视为错误。反斜线是文本。

在您可以取代比对之前,您需要使用 pcre2_compile() 编译正则表达式。您可以将相同的编译正则表达式用于正则表达式比对和正则表达式取代。您不需要比对数据对象进行取代。

调用 pcre2_substitute(),并传递编译的正则表达式、主旨字符串、主旨字符串的长度、正则表达式比对应从字符串中的哪个位置开始,以及比对选项。您可以将 PCRE2_SUBSTITUTE_GLOBAL 与比对选项搭配使用,以取代起始位置之后的所有比对,而不仅仅是第一个比对。下一个参数用于比对数据和比对内容,两者都可以设置为 NULL。然后传递取代字符串和取代字符串的长度。最后传递结果字符串应保存的缓冲区指针,以及保存缓冲区大小的变量指针。缓冲区需要有空间存放终止零。所有长度和偏移量都以代码单位为单位,而非字符。

pcre2_substitute() 传回已取代的正则表达式比对数。零表示未找到任何比对。此函数绝不会传回 PCRE2_ERROR_NOMATCH。负数表示发生错误。调用 pcre2_get_error_message() 以取得错误消息。保存缓冲区大小的变量会更新,以指出写入缓冲区的字符串长度,不包括终止零。(会写入终止零。)

延伸取代字符串语法

从版本 10.21 开始,PCRE2 提供延伸取代字符串语法,您可以在调用 pcre2_substitute() 时将 PCRE2_SUBSTITUTE_EXTENDED 与比对选项搭配使用,以激活此语法。最大的不同是反斜线不再是文本。反斜线后接非字母或数字的字符会转义该字符。因此,您可以使用其他反斜线转义美元符号和反斜线,以取消它们的特殊意义。如果您要在取代字符串中使用文本反斜线,则必须使用另一个反斜线转义它。反斜线后接数字是错误。反斜线后接字母是错误,除非该组合形成取代字符串代码。

\a、\e、\f、\n、\r 和 \t 是常见的 ASCII 控制字符转义字符。特别注意的是,\b 和 \v 不见了。 \x0 到 \xF 和 \x00 到 \xFF 是十六进位转义字符。 \x{0} 到 \x{10FFFF} 会插入 Unicode 编码点。 \o{0} 到 \o{177777} 是八进位转义字符。

大小写转换 也受支持。语法与 Perl 相同,但行为不同。Perl 允许您将 \u 或 \l 与 \L 或 \U 结合,使一个字符变成大写或小写,而其余的字符则相反。使用 PCRE2,任何大小写转换转义字符都会取消前一个转义字符。因此,您无法将它们结合,甚至 \u 或 \l 都会结束 \U 或 \L 的运行。

条件 使用新发明的语法来支持,该语法扩充了反向引用的语法。 ${group:+已比对:未比对} 会在群组参与时插入 已比对,在群组未参与时插入 未比对。您可以在两个选项中使用完整的替换字符串语法,包括其他条件。

大小写转换会运行条件。条件之前有效的任何大小写转换也会套用于条件。如果条件包含其自己的大小写转换转义字符,则这些转义字符会在条件之后仍然有效。因此,您可以使用 ${1:+\U:\L}${2} 来插入第二个捕获组比对到的文本,如果第一个群组有参与,则为大写;如果第一个群组未参与,则为小写。

PCRE2 開放原始碼正規表示式程式庫
  • 简
  • 繁
  • En
關於正規表示式 » 正規表示式工具和實用程式 » PCRE2 開放原始碼正規表示式程式庫

正規表示式工具
grep
語言和程式庫
Boost
Delphi
GNU (Linux)
Groovy
Java
JavaScript
.NET
PCRE (C/C++)
PCRE2 (C/C++)
Perl
PHP
POSIX
PowerShell
Python
R
Ruby
std::regex
Tcl
VBScript
Visual Basic 6
wxWidgets
XML Schema
Xojo
XQuery 和 XPath
XRegExp
資料庫
MySQL
Oracle
PostgreSQL
本網站的更多內容
簡介
正規表示式快速入門
正規表示式教學
替換字串教學
應用程式和語言
正規表示式範例
正規表示式參考
替換字串參考

PCRE2 開放原始碼正規表示式程式庫

PCRE2 是 Perl 相容正規表示式的簡稱,版本 2。它是廣受歡迎的 PCRE 程式庫的後繼版本。這兩個都是由 Philip Hazel 以 C 編寫的開放原始碼程式庫。

第一個 PCRE2 版本給予版本號碼 10.00,以與先前的 PCRE 8.36 明確區分。PCRE 8.37 到 8.44 和任何未來的 PCRE 版本都僅限於修正錯誤。新功能只會新增到 PCRE2。如果您要進行新的開發專案,您應該考慮使用 PCRE2,而不是 PCRE。但是對於已經使用 PCRE 的現有專案,最好還是堅持使用 PCRE。從 PCRE 移轉到 PCRE2 需要對您的原始碼進行重大變更。這樣做的唯一真正原因是使用新的搜尋和取代功能。

PHP 7.3.0 從 PCRE 移轉到 PCRE2,但沒有使用新的 PCRE2 搜尋和取代。它繼續使用 PHP 本身的替換文字語法。

R 4.0.0 也將其 grep 及相關函數從 PCRE 移至 PCRE2。其 sub 及 gsub 函數持續使用 R 本身的替換文字語法。

PCRE2 10.00 至 10.34 及 PCRE 8.36 至 8.44 支援的正規表示式語法大致相同。因此,本網站上 正規表示式教學 中關於 PCRE(或特別是 PCRE 版本 8.36 至 8.44)的說明也適用於 PCRE2。PCRE2 僅在與 PCRE 不同的幾個特定區域中被提及。

正規表示式語法有新的版本檢查條件。該語法很像 檢查命名反向參照的條件,但包含等號(以及擷取群組名稱中不允許的其他符號),使其在原始 PCRE 中成為語法錯誤。在所有版本的 PCRE2 中,(?(VERSION>=10.00)yes|no) 在字串 yesno 中比對 yes。您可以對「yes」和「no」部分使用任何有效的正規表示式。如果版本檢查成功,則會嘗試「yes」部分。否則,會嘗試「no」部分。這完全就像一個正常的條件,根據擷取群組是否參與比對,來評估直線符號前或後的部分。

您可以使用 >= 檢查最小版本,或使用 = 檢查特定版本。 (?(VERSION=10.00)yes|no) 在 PCRE2 10.00 中比對 yes。它在 PCRE2 10.10 和所有後續版本中比對 no。省略次要版本號碼與指定 .00 相同。因此,(?(VERSION>=10)yes|no) 在所有版本的 PCRE2 中比對 yes,但 (?(VERSION=10)yes|no) 僅在 PCRE2 10.00 中比對 yes。如果您指定次要版本號碼,您應該在小數點後使用兩個數字。從版本 10.21 開始,三個或更多數字會產生錯誤。版本 10.21 也變更了個位數數字的詮釋,包括以零開頭的數字。由於第一個版本是 10.00,第二個版本是 10.10,因此不需要檢查個位數數字。如果您指定次要版本號碼,您不能省略小數點。 (?(VERSION>=1000)yes|no) 檢查版本 1000.00 或更高。

此版本檢查條件主要適用於間接使用 PCRE2 的人,透過提供基於 PCRE2 的正規表示式支援或嵌入 PCRE2 但不公開其所有函式呼叫的應用程式或程式語言。它允許他們找出應用程式使用的 PCRE2 版本。如果您使用 PCRE2 C 函式庫開發應用程式,則您應該使用函式呼叫來確定 PCRE2 版本。

char version[255];
pcre2_config(PCRE2_CONFIG_VERSION, version);

UTF-8、UTF-16 或 UTF-32

在原始的 PCRE 函式庫中,UTF-16 和 UTF-32 支援是在後續版本中透過附加函式新增的,這些函式以 pcre16_ 和 pcre32_ 為字首。在 PCRE2 中,所有函式都以 pcre2_ 為字首,並以 _8、_16 或 _32 為字尾,以選取 8 位元、16 位元或 32 位元程式碼單位。如果您從原始碼編譯 PCRE2,您需要將 --enable-pcre2-16 和 --enable-pcre2-32 傳遞給 configure 指令碼,以確保 _16 和 _32 函式可用。

8 位元、16 位元或 32 位元程式碼單位表示 PCRE2 會將您的字串解釋為由單位元組字元、雙位元組字元或四位元組字元組成。若要使用 UTF-8、UTF-16 或 UTF-32,您需要使用具有對應程式碼單位大小的函式,並將 PCRE2_UTF 選項傳遞給 pcre2_compile,以允許字元由多個程式碼單位組成。UTF-8 字元由 1 到 4 個位元組組成。UTF-16 字元由 1 或 2 個字組成。

如果您想要在沒有任何字尾的情況下呼叫 PCRE2 函式,如下所示,那麼您需要將 PCRE2_CODE_UNIT_WIDTH 定義為 8、16 或 32,以使沒有字尾的函式使用 8 位元、16 位元或 32 位元程式碼單位。在包含函式庫之前執行此操作,如下所示

#define PCRE2_CODE_UNIT_WIDTH 8
#include "pcre2.h"

沒有字尾的函式始終使用您定義的程式碼單位大小。具有字尾的函式仍然可用。因此,您的應用程式可以使用具有所有三種程式碼單位大小的正規表示式。但重要的是不要將它們混淆。如果需要將相同的正規表示式與 UTF-8 和 UTF-16 字串比對,則您需要使用 pcre_compile_8 和 pcre_compile_16 編譯它兩次,然後使用對應的 pcre_match_8 和 pcre_match_16 函式使用已編譯的正規表示式。

使用 PCRE2

使用 PCRE2 比使用 PCRE 稍微複雜一些。使用 PCRE2 時,您必須使用各種類型的內容傳遞某些編譯或比對選項,例如換行處理。在 PCRE 中,這些選項可以在編譯或比對時直接傳遞為選項位元。

在使用正規表示式之前,需要將其轉換為二進位格式以提升效率。為此,只需呼叫 pcre2_compile(),並將正規表示式作為字串傳遞。如果字串以 null 結束,則可以將 PCRE2_ZERO_TERMINATED 傳遞為第二個參數。否則,請將長度傳遞為第二個參數中的程式碼單位。對於 UTF-8,這是以位元組為單位的長度,而對於 UTF-16 或 UTF-32,這是以位元組長度除以 2 或 4。第三個參數是一組選項,與二進位或結合。您應該包含 PCRE2_UTF 以獲得適當的 UTF-8、UTF-16 或 UTF-32 支援。如果您省略它,您將獲得純 8 位元、或 UCS-2 或 UCS-4 字元處理。其他常見選項包括 PCRE2_CASELESS、PCRE2_DOTALL、PCRE2_MULTILINE 等。第四和第五個參數接收錯誤條件。最後一個參數是內容。除非您需要特殊換行處理,否則傳遞 NULL。當您完成正規表示式時,函式會傳回指標至其配置的記憶體。您必須使用 pcre2_code_free() 釋放此記憶體。

如果您需要非預設換行處理,您需要呼叫 pcre2_compile_context_create(NULL) 來建立新的編譯內容。然後呼叫 pcre2_set_newline() 傳遞該內容和選項之一,例如 PCRE2_NEWLINE_LF 或 PCRE2_NEWLINE_CRLF。然後將此內容作為最後一個參數傳遞至 pcre2_compile()。您可以對任意數量的正規表示式編譯重複使用相同的內容。當您完成後,請呼叫 pcre2_compile_context_free()。請注意,在原始 PCRE 中,您可以將 PCRE_NEWLINE_LF 等直接傳遞至 pcre_compile()。這不適用於 PCRE2。如果您將 PCRE2_NEWLINE_LF 等傳遞至 pcre2_compile(),PCRE2 也不會抱怨。但這樣做沒有效果。您必須使用比對內容。

在使用已編譯的正規表示式尋找字串中的配對之前,您需要呼叫 pcre2_match_data_create_from_pattern() 來配置儲存配對結果的記憶體。將已編譯的正規表示式傳遞為第一個參數,並將 NULL 傳遞為第二個參數。此函式會傳回已配置記憶體的指標。當您完成配對資料時,您必須使用 pcre2_match_data_free() 釋放此記憶體。您可以重複使用相同的配對資料來多次呼叫 pcre2_match()。

若要尋找配對,請呼叫 pcre2_match() 並傳遞已編譯的正規表示式、主旨字串、整個字串的長度、配對嘗試必須開始的字元的偏移量、配對選項、配對資料物件的指標,以及 NULL 作為內容。長度和起始偏移量以程式碼單位表示,而非字元。當配對成功時,此函式會傳回正數。PCRE2_ERROR_NOMATCH 表示未找到配對。任何其他非正回傳值表示錯誤。可以使用 pcre2_get_error_message() 取得錯誤訊息。

若要找出字串的哪一部分配對,請呼叫 pcre2_get_ovector_pointer()。這會傳回 PCRE2_SIZE 值陣列的指標。您不需要釋放此指標。當您呼叫 pcre2_match_data_free() 時,它將會失效。陣列的長度是 pcre2_match() 傳回的值。陣列中的前兩個值是整體配對的開始和結束。第二對是第一個擷取群組的配對,依此類推。如果您的正規表示式有命名擷取群組,請呼叫 pcre2_substring_number_from_name() 來取得群組號碼。

如果您只想取得配對的文字,您可以使用便利函式,例如 pcre2_substring_copy_bynumber() 或 pcre2_substring_copy_byname()。傳遞擷取群組的號碼或名稱,或傳遞零表示整體配對。使用 pcre2_substring_free() 釋放結果。如果結果不需要以零終止,您可以使用 pcre2_substring_get_bynumber() 和 pcre2_substring_get_byname() 來取得原始主旨字串中配對開始位置的指標。pcre2_substring_length_bynumber() 和 pcre2_substring_length_byname() 會提供配對的長度。

PCRE2 沒有提供函式讓您取得字串中正規表示式的所有配對。它永遠只會傳回第一個配對。若要取得第二個配對,請再次呼叫 pcre2_match() 並傳遞 ovector[1](第一個配對的結束)作為第二個配對嘗試的起始位置。如果第一個配對為零長度,請在傳遞給 pcre2_match() 的選項中包含 PCRE2_NOTEMPTY_ATSTART,以避免再次找到相同的零長度配對。這與在呼叫之前遞增起始位置不同。使用 PCRE2_NOTEMPTY_ATSTART 傳遞前一個配對的結束可能會導致在相同位置找到非零長度的配對。

取代配對

PCRE 願望清單中永遠最大的項目可能是搜尋和取代功能。PCRE2 終於實現了。取代字串語法相當簡單。不過,它與 Perl 不相容。反向參照可以指定為 $group 或 ${group},其中「group」是群組的名稱或編號。整體比對是群組編號 0。若要將文字美元符號新增至取代字串,您需要重複輸入。任何不屬於有效反向參照的單一美元符號都是錯誤。與 Python 相似,但與 Perl 不同,PCRE2 將 不存在群組的反向參照 和 不參與群組的反向參照 視為錯誤。反斜線是文字。

在您可以取代比對之前,您需要使用 pcre2_compile() 編譯正規表示式。您可以將相同的編譯正規表示式用於正規表示式比對和正規表示式取代。您不需要比對資料物件進行取代。

呼叫 pcre2_substitute(),並傳遞編譯的正規表示式、主旨字串、主旨字串的長度、正規表示式比對應從字串中的哪個位置開始,以及比對選項。您可以將 PCRE2_SUBSTITUTE_GLOBAL 與比對選項搭配使用,以取代起始位置之後的所有比對,而不仅仅是第一個比對。下一個參數用於比對資料和比對內容,兩者都可以設定為 NULL。然後傳遞取代字串和取代字串的長度。最後傳遞結果字串應儲存的緩衝區指標,以及儲存緩衝區大小的變數指標。緩衝區需要有空間存放終止零。所有長度和偏移量都以程式碼單位為單位,而非字元。

pcre2_substitute() 傳回已取代的正規表示式比對數。零表示未找到任何比對。此函數絕不會傳回 PCRE2_ERROR_NOMATCH。負數表示發生錯誤。呼叫 pcre2_get_error_message() 以取得錯誤訊息。儲存緩衝區大小的變數會更新,以指出寫入緩衝區的字串長度,不包括終止零。(會寫入終止零。)

延伸取代字串語法

從版本 10.21 開始,PCRE2 提供延伸取代字串語法,您可以在呼叫 pcre2_substitute() 時將 PCRE2_SUBSTITUTE_EXTENDED 與比對選項搭配使用,以啟用此語法。最大的不同是反斜線不再是文字。反斜線後接非字母或數字的字元會跳脫該字元。因此,您可以使用其他反斜線跳脫美元符號和反斜線,以取消它們的特殊意義。如果您要在取代字串中使用文字反斜線,則必須使用另一個反斜線跳脫它。反斜線後接數字是錯誤。反斜線後接字母是錯誤,除非該組合形成取代字串代碼。

\a、\e、\f、\n、\r 和 \t 是常見的 ASCII 控制字元跳脫字元。特別注意的是,\b 和 \v 不見了。 \x0 到 \xF 和 \x00 到 \xFF 是十六進位跳脫字元。 \x{0} 到 \x{10FFFF} 會插入 Unicode 編碼點。 \o{0} 到 \o{177777} 是八進位跳脫字元。

大小寫轉換 也受支援。語法與 Perl 相同,但行為不同。Perl 允許您將 \u 或 \l 與 \L 或 \U 結合,使一個字元變成大寫或小寫,而其餘的字元則相反。使用 PCRE2,任何大小寫轉換跳脫字元都會取消前一個跳脫字元。因此,您無法將它們結合,甚至 \u 或 \l 都會結束 \U 或 \L 的執行。

條件 使用新發明的語法來支援,該語法擴充了反向參照的語法。 ${group:+已比對:未比對} 會在群組參與時插入 已比對,在群組未參與時插入 未比對。您可以在兩個選項中使用完整的替換字串語法,包括其他條件。

大小寫轉換會執行條件。條件之前有效的任何大小寫轉換也會套用於條件。如果條件包含其自己的大小寫轉換跳脫字元,則這些跳脫字元會在條件之後仍然有效。因此,您可以使用 ${1:+\U:\L}${2} 來插入第二個擷取群組比對到的文字,如果第一個群組有參與,則為大寫;如果第一個群組未參與,則為小寫。

The PCRE2 Open Source Regex Library
  • 简
  • 繁
  • En
About Regular Expressions » Tools and Utilities for Regular Expressions » The PCRE2 Open Source Regex Library

Regex Tools
grep
Languages & Libraries
Boost
Delphi
GNU (Linux)
Groovy
Java
JavaScript
.NET
PCRE (C/C++)
PCRE2 (C/C++)
Perl
PHP
POSIX
PowerShell
Python
R
Ruby
std::regex
Tcl
VBScript
Visual Basic 6
wxWidgets
XML Schema
Xojo
XQuery & XPath
XRegExp
Databases
MySQL
Oracle
PostgreSQL
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

The PCRE2 Open Source Regex Library

PCRE2 is short for Perl Compatible Regular Expressions, version 2. It is the successor to the widely popular PCRE library. Both are open source libraries written in C by Philip Hazel.

The first PCRE2 release was given version number 10.00 to make a clear break with the preceding PCRE 8.36. PCRE 8.37 through 8.44 and any future PCRE releases are limited to bug fixes. New features are added to PCRE2 only. If you’re taking on a new development project, you should consider using PCRE2 instead of PCRE. But for existing projects that already use PCRE, it’s probably best to stick with PCRE. Moving from PCRE to PCRE2 requires significant changes to your source code. The only real reason to do so would be to use the new search-and-replace feature.

PHP 7.3.0 moved from PCRE to PCRE2 but does not use the new PCRE2 search-and-replace. It continues to use PHP’s own replacement text syntax.

R 4.0.0 also moved its grep and related functions from PCRE to PCRE2. Its sub and gsub functions continue to use R’s own replacement text syntax.

The regex syntax supported by PCRE2 10.00 through 10.34 and PCRE 8.36 through 8.44 is pretty much the same. Because of this, everything the regex tutorial on this website says about PCRE (or PCRE versions 8.36 through 8.44 in particular) also applies to PCRE2. PCRE2 is only mentioned in the few specific areas where it differs from PCRE.

The regex syntax has a new version check conditional. The syntax looks much like a conditional that checks a named backreference, but the inclusion of the equals sign (and other symbols not allowed in capturing group names) make it a syntax error in the original PCRE. In all versions of PCRE2, (?(VERSION>=10.00)yes|no) matches yes in the string yesno. You can use any valid regex for the “yes” and “no” parts. If the version check succeeds the “yes” part is attempted. Otherwise the “no” part is attempted. This is exactly like a normal conditional that evaluates the part before or after the vertical bar depending on whether a capturing group participated in the match or not.

You can use >= to check for a minimum version, or = to check for a specific version. (?(VERSION=10.00)yes|no) matches yes in PCRE2 10.00. It matches no in PCRE2 10.10 and all later versions. Omitting the minor version number is the same as specifying .00. So (?(VERSION>=10)yes|no) matches yes in all versions of PCRE2, but (?(VERSION=10)yes|no) only matches yes in PCRE2 10.00. If you specify the minor version number you should use two digits after the decimal point. Three or more digits are an error as of version 10.21. Version 10.21 also changes the interpretation of single digit numbers, including those specified with a leading zero. Since the first release was 10.00 and the second release was 10.10 there should be no need to check for single digit numbers. You cannot omit the dot if you specify the minor version number. (?(VERSION>=1000)yes|no) checks for version 1000.00 or greater.

This version check conditional is mainly intended for people who use PCRE2 indirectly, via an application that provides regex support based on PCRE2 or a programming language that embeds PCRE2 but does not expose all its function calls. It allows them to find out which version of PCRE2 the application uses. If you are developing an application with the PCRE2 C library then you should use a function call to determine the PCRE2 version:

char version[255];
pcre2_config(PCRE2_CONFIG_VERSION, version);

UTF-8, UTF-16, or UTF-32

In the original PCRE library, UTF-16 and UTF-32 support were added in later versions through additional functions prefixed with pcre16_ and pcre32_. In PCRE2, all functions are prefixed with pcre2_ and suffixed with _8, _16, or _32 to select 8-bit, 16-bit, or 32-bit code units. If you compile PCRE2 from source, you need to pass --enable-pcre2-16 and --enable-pcre2-32 to the configure script to make sure the _16 and _32 functions are available.

8-bit, 16-bit, or 32-bit code units means that PCRE2 interprets your string as consisting of single byte characters, double byte characters, or quad byte characters. To work with UTF-8, UTF-16, or UTF-32, you need to use the functions with the corresponding code unit size, and pass the PCRE2_UTF option to pcre2_compile to allow characters to consists of multiple code units. UTF-8 characters consist of 1 to 4 bytes. UTF-16 characters consist of 1 or 2 words.

If you want to call the PCRE2 functions without any suffix, as they are shown below, then you need to define PCRE2_CODE_UNIT_WIDTH as 8, 16, or 32 to make the functions without a suffix use 8-bit, 16-bit, or 32-bit code units. Do so before including the library, like this:

#define PCRE2_CODE_UNIT_WIDTH 8
#include "pcre2.h"

The functions without a suffix always use the code unit size you’ve defined. The functions with suffixes remain available. So your application can use regular expressions with all three code unit sizes. But it is important not to mix them up. If the same regex needs to be matched against UTF-8 and UTF-16 strings, then you need to compile it twice using pcre_compile_8 and pcre_compile_16 and then use the compiled regexes with the corresponding pcre_match_8 and pcre_match_16 functions.

Using PCRE2

Using PCRE2 is a bit more complicated than using PCRE. With PCRE2 you have to use various types of context to pass certain compilation or matching options, such as line break handling. In PCRE these options could be passed directly as option bits when compiling or matching.

Before you can use a regular expression, it needs to be converted into a binary format for improved efficiency. To do this, simply call pcre2_compile() passing your regular expression as a string. If the string is null-terminated, you can pass PCRE2_ZERO_TERMINATED as the second parameter. Otherwise, pass the length in code units as the second parameter. For UTF-8 this is the length in bytes, while for UTF-16 or UTF-32 this is the length in bytes divided by 2 or 4. The 3rd parameter is a set of options combined with binary or. You should include PCRE2_UTF for proper UTF-8, UTF-16, or UTF-32 support. If you omit it, you get pure 8-bit, or UCS-2, or UCS-4 character handling. Other common options are PCRE2_CASELESS, PCRE2_DOTALL, PCRE2_MULTILINE, and so on. The 4th and 5th parameters receive error conditions. The final parameter is a context. Pass NULL unless you need special line break handling. The function returns a pointer to memory it allocated. You must free this with pcre2_code_free() when you’re done with the regular expression.

If you need non-default line break handling, you need to call pcre2_compile_context_create(NULL) to create a new compile context. Then call pcre2_set_newline() passing that context and one of the options like PCRE2_NEWLINE_LF or PCRE2_NEWLINE_CRLF. Then pass this context as the final parameter to pcre2_compile(). You can reuse the same context for as many regex compilations as you like. Call pcre2_compile_context_free() when you’re done with it. Note that in the original PCRE, you could pass PCRE_NEWLINE_LF and the like directly to pcre_compile(). This does not work with PCRE2. PCRE2 will not complain if you pass PCRE2_NEWLINE_LF and the like to pcre2_compile(). But doing so has no effect. You have to use the match context.

Before you can use the compiled regular expression to find matches in a string, you need to call pcre2_match_data_create_from_pattern() to allocate memory to store the match results. Pass the compiled regex as the first parameter, and NULL as the second. The function returns a pointer to memory it allocated. You must free this with pcre2_match_data_free() when you’re done with the match data. You can reuse the same match data for multiple calls to pcre2_match().

To find a match, call pcre2_match() and pass the compiled regex, the subject string, the length of the entire string, the offset of the character where the match attempt must begin, matching options, the pointer to the match data object, and NULL for the context. The length and starting offset are in code units, not characters. The function returns a positive number when the match succeeds. PCRE2_ERROR_NOMATCH indicates no match was found. Any other non-positive return value indicates an error. Error messages can be obtained with pcre2_get_error_message().

To find out which part of the string matched, call pcre2_get_ovector_pointer(). This returns a pointer to an array of PCRE2_SIZE values. You don’t need to free this pointer. It will become invalid when you call pcre2_match_data_free(). The length of the array is the value returned by pcre2_match(). The first two values in the array are the start and end of the overall match. The second pair is the match of the first capturing group, and so on. Call pcre2_substring_number_from_name() to get group numbers if your regex has named capturing groups.

If you just want to get the matched text, you can use convenience functions like pcre2_substring_copy_bynumber() or pcre2_substring_copy_byname(). Pass the number or name of a capturing group, or zero for the overall match. Free the result with pcre2_substring_free(). If the result doesn’t need to be zero-terminated, you can use pcre2_substring_get_bynumber() and pcre2_substring_get_byname() to get a pointer to the start of the match within the original subject string. pcre2_substring_length_bynumber() and pcre2_substring_length_byname() give you the length of the match.

PCRE2 does not provide a function that gives you all the matches of a regex in string. It never returns more than the first match. To get the second match, call pcre2_match() again and pass ovector[1] (the end of the first match) as the starting position for the second match attempt. If the first match was zero-length, include PCRE2_NOTEMPTY_ATSTART with the options passed to pcre2_match() in order to avoid finding the same zero-length match again. This is not the same as incrementing the starting position before the call. Passing the end of the previous match with PCRE2_NOTEMPTY_ATSTART may result in a non-zero-length match being found at the same position.

Substituting Matches

The biggest item item that was forever on PCRE’s wishlist was likely the ability to search-and-replace. PCRE2 finally delivers. The replacement string syntax is fairly simple. There is nothing Perl-compatible about it, though. Backreferences can be specified as $group or ${group} where “group” is either the name or the number of a group. The overall match is group number zero. To add literal dollar sign to the replacement, you need to double it up. Any single dollar sign that is not part of a valid backreference is an error. Like Python, but unlike Perl, PCRE2 treats backreferences to non-existent groups and backreferences to non-participating groups as errors. Backslashes are literals.

Before you can substitute matches, you need to compile your regular expression with pcre2_compile(). You can use the same compiled regex for both regex matching and regex substitution. You don’t need a match data object for substitution.

Call pcre2_substitute() and pass it the compiled regex, the subject string, the length of the subject string, the position in the string where regex matching should begin, and the matching options. You can include PCRE2_SUBSTITUTE_GLOBAL with the matching options to replace all matches after the starting position, instead of just the first match. The next parameters are for match data and match context which can both be set to NULL. Then pass the replacement string and the length of the replacement string. Finally pass a pointer to a buffer where the result string should be stored, along with a pointer to a variable that holds the size of the buffer. The buffer needs to have space for a terminating zero. All lengths and offsets are in code units, not characters.

pcre2_substitute() returns the number of regex matches that were substituted. Zero means no matches were found. This function never returns PCRE2_ERROR_NOMATCH. A negative number indicates an error occurred. Call pcre2_get_error_message() to get the error message. The variable that holds the size of the buffer is updated to indicate the length of the string that it written to the buffer, excluding the terminating zero. (The terminating zero is written.)

Extended Replacement String Syntax

Starting with version 10.21, PCRE2 offers an extended replacement string syntax that you can enable by including PCRE2_SUBSTITUTE_EXTENDED with the matching options when calling pcre2_substitute(). The biggest difference is that backslashes are no longer literals. A backslash followed by a character that is not a letter or digit escapes that character. So you can escape dollar signs and backslashes with other backslashes to suppress their special meaning. If you want to have a literal backslash in your replacement, then you have to escape it with another backslash. Backslashes followed by a digit are an error. Backslashes followed by a letter are an error, unless that combination forms a replacement string token.

\a, \e, \f, \n, \r, and \t are the usual ASCII control character escapes. Notably missing are \b and \v. \x0 through \xF and \x00 through \xFF are hexadecimal escapes. \x{0} through \x{10FFFF} insert a Unicode code point. \o{0} through \o{177777} are octal escapes.

Case conversion is also supported. The syntax is the same as Perl, but the behavior is not. Perl allows you to combine \u or \l with \L or \U to make one character uppercase or lowercase and the remainder the opposite. With PCRE2, any case conversion escape cancels the preceding escape. So you can’t combine them and even \u or \l will end a run of \U or \L.

Conditionals are supported using a newly invented syntax that extends the syntax for backreferences. ${group:+matched:unmatched} inserts matched when the group participated and unmatched when it didn’t. You can use the full replacement string syntax in the two alternatives, including other conditionals.

Case conversion runs through conditionals. Any case conversion in effect before the conditional also applies to the conditional. If the conditional contains its own case conversion escapes in the part of the conditional that is actually used, then those remain in effect after the conditional. So you could use ${1:+\U:\L}${2} to insert the text matched by the second capturing group in uppercase if the first group participated, and in lowercase if it didn’t.

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