我想知道匹配埃及象形文字的正则表达式。我完全无能为力,需要你的帮助。
我不能发信,因为堆栈溢出似乎无法识别它。
所以任何人都可以告诉我这些角色的unicode范围。
答案 0 :(得分:38)
TLDNR:\p{Egyptian_Hieroglyphs}
Egyptian_Hieroglyphs属于“星体”平面,它使用超过16位来编码字符。从ES5开始,Javascript不支持星体平面(more on that),因此您必须使用代理对。第一个代理是
U+13000 = d80c dc00
最后一个是
U+1342E = d80d dc2e
给出了
re = /(\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E])+/g
t = document.getElementById("pyramid").innerHTML
document.write("<h1>Found</h1>" + t.match(re))
<div id="pyramid">
some really old stuff
</div>
这是安装Noto Sans Egyptian Hieroglyphs时的样子:
在支持UCS-4的平台上,您可以直接使用埃及代码点13000
到1342F
,但语法因系统而异。例如,在Python(3.3 up)中它将是[\U00013000-\U0001342E]
:
>>> s = "some \U+13000 really \U+13001 old \U+1342C stuff \U+1342D \U+1342E"
>>> s
'some really old stuff '
>>> import re
>>> re.findall('[\U00013000-\U0001342E]', s)
['', '', '', '', '']
最后,如果您的正则表达式引擎支持unicode属性,您可以(并且应该)使用这些而不是硬编码范围。例如在php / pcre中:
$str = " some really old stuff ";
preg_match_all('~\p{Egyptian_Hieroglyphs}~u', $str, $m);
print_r($m);
打印
[0] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
[4] =>
)
答案 1 :(得分:10)
Unicode编码Egyptian hieroglyphs,范围为U + 13000 - U + 1342F(超出基本多语言平面)。
在这种情况下,有两种方法可以编写正则表达式:
通过指定U + 13000 - U + 1342F的字符范围。
虽然在BMP中为字符指定正则表达式中的字符范围就像[a-z]
一样简单,但根据语言支持,对星体平面中的字符这样做可能不那么简单。
通过为埃及象形文字指定Unicode块
由于我们匹配埃及象形文字块中的任何字符,因此这是编写支持可用的正则表达式的首选方法。
(目前,我还不知道Java类库的其他实现如何处理Pattern
类中的星体平面字符。)
我不确定在Java 1.4中讨论星体平面中匹配字符是否有意义,因为只有通过改进现有的String实现(使用UCS-2)才能在Java 5中添加对BMP之外的字符的支持。对于其内部字符串表示),使用代码点感知方法。
由于Java继续允许在String中指定单独的代理(一个不能与其他代理形成一对),它导致一团糟,因为代理不是真正的字符,而且单独的代理在UTF-16中无效。
Pattern
类看到了从Java 1.4.x到Java 5的重大改进,因为该类被重写以支持在星体平面中匹配Unicode字符:模式字符串之前被转换为代码点数组它被解析,输入字符串由String类中的代码点感知方法遍历。
You can read more about the madness in Java regex in this answer by tchist.
我已经详细解释了如何匹配涉及星界平面字符in this answer的一系列角色,所以我只想在这里包含代码。它还包括一些错误尝试编写正则表达式以匹配星体平面字符的反例。
"[\uD80C\uDC00-\uD80D\uDC2F]"
"[\\uD80C\\uDC00-\\uD80D\\uDC2F]"
"[\\x{13000}-\\x{1342F}]"
由于我们匹配的任何代码点都属于Unicode块,因此它也可以写成:
"\\p{InEgyptian_Hieroglyphs}"
"\\p{InEgyptian Hieroglyphs}"
"\\p{InEgyptianHieroglyphs}"
"\\p{block=EgyptianHieroglyphs}"
"\\p{blk=Egyptian Hieroglyphs}"
自1.4以来,Java支持\p
Unicode块的语法,但仅在Java 7中添加了对埃及象形文字块的支持。
PHP示例已涵盖在georg's answer中:
'~\p{Egyptian_Hieroglyphs}~u'
请注意,如果您希望按代码点匹配而不是按代码单位进行匹配,则u
标志是必需的。
不确定StackOverflow上是否有更好的帖子,但是I have written some explanation on the effect of u
flag (UTF mode) in this answer of mine。
有一点需要注意,Egyptian_Hieroglyphs
仅适用于PCRE 8.02(或不早于PCRE 7.90的版本)。
作为替代方案,您可以使用\x{h...hh}
语法指定字符范围:
'~[\x{13000}-\x{1342F}]~u'
请注意强制性u
标记。
至少PCRE 4.50支持\x{h...hh}
语法。
georg's answer已经涵盖了字符范围方法(这是在vanilla JavaScript中执行此操作的唯一方法)。修改正则表达式以覆盖整个块,包括保留的未分配代码点。
/(?:\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F])/
上面的解决方案演示了匹配星体平面中一系列字符的技术,以及JavaScript RegExp的限制。
JavaScript也遇到与Java相同的字符串表示问题。虽然Java确实在Java 5中修复了Pattern
类以允许它使用代码点,但JavaScript RegExp
仍然停留在UCS-2时代,迫使我们使用代码单元而不是代码点在正则表达式中。
最后,在ECMAScript 6中添加了对代码点匹配的支持,可通过u
标志提供,以防止破坏以前版本的ECMAScript中的现有实现。
点击上面第二个链接的Support部分,查看为ES6 RegExp
提供实验支持的浏览器列表。
在ES6中引入\u{h...hh}
语法后,可以用类似于Java 7的方式重写字符范围:
/[\u{13000}-\u{1342F}]/u
或者您也可以直接在RegExp
字面值中指定字符,但意图并不像[a-z]
那样明确:
/[-]/u
请注意上面两个正则表达式中的u
修饰符。
还是被ES5困住了吗?不用担心,您可以使用regxpu将ES6 Unicode RegExp转换为ES5 RegExp。