为n字节插入正后视会有什么后果,(?
至少在 PHP 中,正则表达式匹配函数(
preg_match
和 preg_match_all
)允许在给定的字节偏移量之后开始匹配。在任何其他PCRE PHP函数中都没有相应的功能 - 例如,您可以指定preg_replace
完成的替换次数限制,但不能指定这些替换的匹配必须在n字节之后发生。
对性能和可读性显然会有一些(姑且称之为微不足道的)后果,但是会有任何(不可忽视的)影响吗,比如匹配变成不匹配(除非它们没有偏移n个字节)或者替换变得畸形?
一些例子:
< code>/some expression/
变成了< code>/(?
/(this) has (groups)/i
变为 /(?
据我所知,从我运行的有限测试来看,添加此回溯可以有效地模拟此偏移参数,并且不会弄乱任何其他回溯、替换或其他控制模式;但我也不是正则表达式的专家。
我试图确定通过在模式中插入n字节的look back来构建替换/过滤函数扩展是否有任何可能的后果。它应该像match函数的offset参数一样工作——因此,简单地对< code>substr( $subject,$offset )
运行表达式是行不通的,原因与它对< code>preg_match不起作用的原因相同(最值得注意的是,它切断了任何lookbehinds,然后^
错误地匹配子字符串的开头,而不是原始字符串)。
你可以试试< code>/(?
假设您与PHP捆绑的PCRE库被编译为8位库(UTF-8),那么在非UTF模式下
\C
相当于
[\x00-\xff]
和
(?s:.)
它们中的任何一个都可以在后面查看中用作preg_match
和preg_match_all
函数中offset
字段的替换。
在非 UTF 模式下,它们都匹配 1 个数据单元,即 8 位 (UTF-8) PCRE 库中的 1 个字节,并且它们匹配所有 256 个可能的不同值。
UTF模式可以通过传递给< code>preg_*函数的模式中的< code>u标志激活,或者通过在模式开头指定< code>(*UTF8)、< code>(*UTF16)、< code>(*UTF32)动词激活。
在UTF模式下,字符类[]
和点元字符。
将匹配Unicode字符有效范围内的一个代码点,并且不是代理。由于一个代码点可以在UTF-8中编码为1到4个字节,并且由于UTF-8的编码方案,因此无法使用字符类构造来匹配0x80到0xFF范围内的值的单个字节。
虽然< code>\C是专门设计来匹配一个数据单元(在UTF-8中是一个字节),而不管UTF模式是否打开,但它在UTF模式的后视构造中不受支持。
我不知道是否有人实际编译16位或32位PCRE库,将其包含在PHP库中并实际使其工作。如果有人知道这种构造在野外被广泛使用,请告诉我。实际上,我不知道PHP中的字符串和偏移量是如何传递给PCRE的C API的,这取决于< code>preg_*函数的不同结果。
在PCRE库C API级别,您只能使用数据单元,对于8位库,数据单元以8位为单位;对于16位库,数据单元以16位为单位;对于32位库,数据单元以32位为单位。
对于8位库(UTF-8),1个数据单元是8位或1个字节,因此无论是作为函数的参数还是作为正则表达式构造,以字节为单位指定偏移量都没有太大障碍。
在非UTF模式下,字符类[]
、点。
和\C
正好匹配1个数据单元。
>
\C
匹配1个数据单元,无论是UTF模式还是非UTF模式。但是,它不能在UTF模式下用于look behind。
匹配单个数据单元
在字符类之外,转义序列< code>\C匹配任何一个数据单元,不管是否设置了UTF模式。
<代码>在非UTF模式下匹配1个数据单元。
关于 UTF 模式的一般评论
[...]
字符类在非 UTF 模式下匹配 1 个数据单元。文档没有明确说明这一点,但措辞暗示了这一点。
方括号和字符类
[...]
字符类匹配主题中的单个字符。在UTF模式中,该字符可能超过一个数据单元长。
同样的结论可以通过查看\x{hh…}
语法的上限来指定非UTF模式下的十六进制代码。通过测试,关于代理的最后一个子句似乎不适用于非UTF模式。
使用八进制或十六进制数字指定的字符仅限于某些值,如下所示:
8-bit non-UTF mode less than 0x100
8-bit UTF-8 mode less than 0x10ffff and a valid codepoint
16-bit non-UTF mode less than 0x10000
16-bit UTF-16 mode less than 0x10ffff and a valid codepoint
32-bit non-UTF mode less than 0x100000000
32-bit UTF-32 mode less than 0x10ffff and a valid codepoint
无效的Unicode代码点范围为0xd800到0xdfff(所谓的“代理”代码点)和0xffef。
所有提供和返回的偏移量都以数据单元数为单位:
要与 pcre_exec()
匹配的字符串
主题字符串作为主题
中的指针、长度
中的长度和起始偏移量的起始
偏移量传递给 pcre_exec()。
长度
和起始偏移
量的单位是 8 位库的字节、16 位库的 16 位数据项和 32 位库的 32 位数据项。
< code>pcre_exec()如何返回捕获的子字符串
[...]
当匹配成功时,有关捕获的子字符串的信息将以整数对的形式返回,从ovector的开头开始,最多持续到其长度的三分之二。每对的第一个元素设置为子字符串中第一个字符的偏移量,第二个元素设置为子字符串结束后第一个字符的偏移量。即使在UTF模式下,这些值也始终是数据单位偏移量。
是否有一种简单的方法可以使用另一个正则表达式(考虑括号内的情况)从正则表达式中删除正/负lookback/lookahead组? 示例源表达式:
我肯定这已经张贴之前,但我有麻烦找到一个答案。
问题内容: 据我所知,MySQL不支持从正则表达式匹配中检索捕获组的值。我发现了一个服务器端扩展(lib_mysqludf_preg),它将添加此功能,但无法在我的环境中安装此扩展。 因此,我正在寻找一种方法来模拟将正则表达式匹配的一部分捕获为SQL查询中的一列。 我的数据如下所示(并且我无法更改服务器上的数据格式): 我正在寻找每行的最后4位数字。数字始终是值的最后一部分,并且始终由点分隔。以下
我需要编写一个具有以下规则的正则表达式: null null 这些示例无效: > 12--11(因为它包含两个连字符) 1-2345(因为它包含5号) <>是字符出现在最后一个位置,那么在字符之前必须有一个数字not hypen。 即11-A(必须不及格)11-1A(必须及格)
我是正则表达式的初学者,并尝试搜索特定的数字模式。以下数据以 XML 格式嵌入。 要求是提取数据(最里面的列表)。在这个例子中,数据从24779开始到24760。注意:每次数据可能不是从“24”开始。因此,我计划通过以下逻辑提取:如果标签名(在本例中:DUT_1_PC)具有非零的有效数据,并且有效数据的计数大于100,用逗号分隔,则提取该列表及其标签名(DUT_1_PC)。 我无法提取所需的数据。