首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >正则表达式中的最大十六进制值

正则表达式中的最大十六进制值
EN

Stack Overflow用户
提问于 2014-01-07 00:31:55
回答 4查看 3.1K关注 0票数 20

在不使用u标志的情况下,可以使用的十六进制范围是[\x{00}-\x{ff}],但是如果使用u标志,则可以使用4字节值\x{7fffffff} ([\x{00000000}-\x{7fffffff}])。

因此,如果我执行以下代码:

代码语言:javascript
复制
preg_match("/[\x{00000000}-\x{80000000}]+/u", $str, $match);

将收到此错误

代码语言:javascript
复制
Warning: preg_match(): Compilation failed: character value in \x{...} sequence is too large

所以我不能匹配一个像这样的字母和等价的十六进制值f0 a1 83 81。问题不是如何匹配这些字母,而是这个范围&这个边界来自as u修饰符应该如何将字符串视为UTF-16

代码语言:javascript
复制
echo PCRE_VERSION;

使用PHP 5.3.24 - 5.3.28、5.4.14 -5.5.7的PCRE版本:

代码语言:javascript
复制
8.32 2012-11-30

带有PHP 5.3.19 - 5.3.23、5.4.9 -5.4.13的PCRE版本:

代码语言:javascript
复制
8.31 2012-07-06

http://3v4l.org/CrPZ8

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-05-29 01:48:17

所以我不能将一个字母与f0 a1 83 81的十六进制值相匹配。问题不是如何匹配这些字母,而是这个范围&这个边界来自于u修饰符,应该如何将字符串视为UTF-16

您将两个概念混合在一起,这导致了这种混淆。

F0 A1 83 81不是字符的十六进制值。这是UTF-8对字节流中该字符的码位进行编码的方式。

PHP支持\x{}模式的UTF-16代码点是正确的,但是{}中的值表示UTF-16代码点,而不是用于编码字节流中给定字符的实际字节。

因此,您可以在\x{}中使用的最大值实际上是10FFFF

为了与PHP相匹配,你需要使用它的代码点,正如@minitech在他的评论中所建议的那样,它是\x{0210c1}

PCRE documentation"Validity of strings"一节中引用了进一步的解释。

在进行任何其他处理之前检查整个字符串。除了检查字符串的格式外,还会进行检查以确保所有代码点都在U+0到U+10FFFF的范围内,不包括代理区域。所谓的“非字符”代码点没有被排除在外,因为Unicode勘误#9清楚地表明它们不应该被排除在外。

Unicode的“代理区”中的字符保留供UTF-16使用,在UTF-16中,它们成对使用,以编码具有大于0xFFFF的值的代码点。由UTF-16对编码的代码点在UTF-8和UTF-32编码中独立可用。(换句话说,整个代理的事情是对UTF-16的捏造,它不幸地搞乱了UTF-8和UTF-32。)

票数 4
EN

Stack Overflow用户

发布于 2015-05-25 03:59:09

我对php不是很确定,但是在代码点上确实没有调控器。

因此,只有大约110万个有效数据并不重要。

这可能会随时发生变化,但这并不是真正取决于引擎

来执行这一点。有保留的cp是在有效范围内的孔,

有效范围内有代孕,原因不胜枚举

除了字长之外,没有其他限制。

对于UTF- 32,您不能超过31位,因为32是符号位。

0x00000000 - 0x7FFFFFFF

这是有意义的,因为unsigned int作为一种数据类型是32位硬件寄存器的自然大小。

对于UTF- 16,更准确地说,您可以看到相同的限制被屏蔽到16位。位32仍然是符号位,将0x0000 - 0xFFFF保留为有效范围。

通常,如果你使用支持ICU的引擎,你应该能够使用它,

它将source和regex都转换为UTF-32。Boost Regex就是这样一个引擎。

编辑:

关于UTF-16

我猜当Unicode超过16位时,他们在16位代理对的范围内打了一个洞。但它只在两个对之间留下了总共20个可用的比特。

每个代理中有10位,其它6位用于确定hi或L0。

看起来这给Unicode人员留下了20位的限制+额外的0xFFFF舍入,总共有0x10FFFF代码点,有不可用的漏洞。

能够将所有码点转换为不同的编码(8/16/32)

实际上必须是可转换的。因此,永远向后兼容的20位是

他们早先遇到的陷阱,但现在必须接受。

无论如何,正则表达式引擎不会在短期内强制实施这一限制,可能永远不会。

就代理而言,它们就是空洞,格式错误的文本代理不能在模式之间转换。这只适用于转换期间的文字编码字符,而不是一个字符的十六进制表示。例如,很容易在UTF-16 (仅限)模式下搜索未配对的代理,甚至是配对的代理。

但我猜正则表达式引擎并不真正关心漏洞或限制,它们只关心主题字符串处于什么模式。不,引擎不会说:

‘嘿,等等,模式是UTF-16我最好把\x{210C1}转换成\x{D844}\x{DCC1}__。等等,如果我这样做了,如果它的量化\x{210C1}+__,开始在它周围注入正则表达式构造怎么办?更糟糕的是,如果它在[\x{210C1}]__类中呢?不..最好将它限制为\x{FFFF}__。

我使用了一些非常好用的伪代码代理转换:

代码语言:javascript
复制
 Definitions:
 ====================
 10-bits
  3FF = 000000  1111111111

 Hi Surrogate
 D800 = 110110  0000000000
 DBFF = 110110  1111111111 

 Lo Surrogate
 DC00 = 110111  0000000000
 DFFF = 110111  1111111111


 Conversions:
 ====================
 UTF-16 Surrogates to UTF-32
 if ( TESTFOR_SURROGATE_PAIR(hi,lo) )
 {
    u32Out = 0x10000 + (  ((hi & 0x3FF) << 10) | (lo & 0x3FF)  );
 }

 UTF-32 to UTF-16 Surrogates
 if ( u32In >= 0x10000)
 {
    u32In -= 0x10000;
    hi = (0xD800 + ((u32In & 0xFFC00) >> 10));
    lo = (0xDC00 + (u32In & 0x3FF));
 }

 Macro's:
 ====================
 #define TESTFOR_SURROGATE_HI(hs) (((hs & 0xFC00)) == 0xD800 )
 #define TESTFOR_SURROGATE_LO(ls) (((ls & 0xFC00)) == 0xDC00 )
 #define TESTFOR_SURROGATE_PAIR(hs,ls) ( (((hs & 0xFC00)) == 0xD800) && (((ls & 0xFC00)) == 0xDC00) )
 //
 #define PTR_TESTFOR_SURROGATE_HI(ptr) (((*ptr & 0xFC00)) == 0xD800 )
 #define PTR_TESTFOR_SURROGATE_LO(ptr) (((*ptr & 0xFC00)) == 0xDC00 )
 #define PTR_TESTFOR_SURROGATE_PAIR(ptr) ( (((*ptr & 0xFC00)) == 0xD800) && (((*(ptr+1) & 0xFC00)) == 0xDC00) )
票数 1
EN

Stack Overflow用户

发布于 2015-05-28 18:27:14

正如minitech在第一条评论中建议的那样,你必须使用代码点-对于这个字符,它是\x{210C1}。这也是UTF-32中的编码形式。F0 AF AB BF是UTF8编码的序列(参见http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=210C1)。

在某些版本的PCRE中,您可以使用高达\x{7FFFFFFF}的值。但我真的不知道有什么可以与之匹配。

引用http://www.pcre.org/pcre.txt

在UTF-16模式下,字符代码为Unicode,范围为0到0x10ffff,但0xd800到0xdfff范围内的值除外,因为这些是成对使用的“代理”值,用于编码大于0xffff的值。..。在UTF-32模式下,字符代码为Unicode,范围为0到0x10ffff,但0xd800到0xdfff范围内的值除外,因为这些值在UTF-32中是格式错误的“代理”值。

0x10ffff是可用于匹配字符的最大值(这就是我从这里提取的值)。0x10ffff目前也是unicode标准中定义的最大代码点(参见What are some of the differences between the UTFs?) -因此上面的每个值都没有任何意义(或者我就是不明白)……

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20954580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档