正则表达式匹配埃及象形文字

67 regex unicode internationalization

我想知道一个匹配埃及象形文字的正则表达式.我完全无能为力,需要你的帮助.

我无法发布信件,因为堆栈溢出似乎无法识别它.

所以任何人都可以让我知道这些角色的unicode范围.

geo*_*org 38

TLDNR: \p{Egyptian_Hieroglyphs}

使用Javascript

Egyptian_Hieroglyphs属于"星界"平面,使用超过16位来编码角色.从ES5开始,Javascript不支持星体平面(更多内容)因此你必须使用代理对.第一个代理是

U+13000 = d80c dc00
Run Code Online (Sandbox Code Playgroud)

最后一个是

U+1342E = d80d dc2e
Run Code Online (Sandbox Code Playgroud)

这给了

re = /(\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E])+/g

t = document.getElementById("pyramid").innerHTML
document.write("<h1>Found</h1>" + t.match(re))
Run Code Online (Sandbox Code Playgroud)
<div id="pyramid">

  some     	really    	old    	stuff    	    
  
  </div>
Run Code Online (Sandbox Code Playgroud)

这是安装了Noto Sans埃及象形文字的样子:

在此输入图像描述

其他语言

在支持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)
['', '', '', '', '']
Run Code Online (Sandbox Code Playgroud)

最后,如果您的正则表达式引擎支持unicode属性,您可以(并且应该)使用这些而不是硬编码范围.例如在php/pcre中:

$str = " some  really  old  stuff   ";

preg_match_all('~\p{Egyptian_Hieroglyphs}~u', $str, $m);
print_r($m);
Run Code Online (Sandbox Code Playgroud)

版画

[0] => Array
    (
        [0] => 
        [1] => 
        [2] => 
        [3] => 
        [4] => 
    )
Run Code Online (Sandbox Code Playgroud)


nha*_*tdh 10

Unicode编码埃及象形文字,范围从U + 13000 - U + 1342F(超出基本多语言平面).

在这种情况下,有两种方法可以编写正则表达式:

  1. 通过指定U + 13000 - U + 1342F的字符范围.

    虽然在BMP中为字符指定正则表达式中的字符范围非常简单[a-z],但根据语言支持,对星体平面中的字符这样做可能并不那么简单.

  2. 通过为埃及象形文字指定Unicode块

    由于我们匹配埃及象形文字块中的任何字符,因此这是编写可获得支持的正则表达式的首选方法.

Java的

(目前,我不知道Java类库的其他实现如何处理类中的星体平面字符Pattern).

Sun/Oracle实施

我不确定在Java 1.4中讨论星体平面中匹配字符是否有意义,因为通过改进现有的String实现(使用UCS-2作为其内部字符串表示),仅在Java 5中添加了对BMP之外的字符的支持. )使用代码点感知方法.

由于Java继续允许单独的代理(一个不能与其他代理形成一对)在String中指定,因此代理不是真正的字符,并且单独的代理在UTF-16中无效.

Pattern class看到了从Java 1.4.x到Java 5的重大改进,因为该类被重写以支持在星体平面中匹配Unicode字符:模式字符串在解析之前转换为代码点数组,并且输入字符串String类中的代码点感知方法遍历.

你可以通过tchist在这个答案中阅读更多关于Java正则表达式中的疯狂内容.

我已经写了一个关于如何在这个答案中匹配涉及星界平面字符的一系列字符的详细解释,所以我只想在这里包含代码.它还包括一些错误尝试编写正则表达式来匹配星体平面字符的反例.

Java 5(及以上)

"[\uD80C\uDC00-\uD80D\uDC2F]"
Run Code Online (Sandbox Code Playgroud)

Java 7(及以上)

"[\\uD80C\\uDC00-\\uD80D\\uDC2F]"
"[\\x{13000}-\\x{1342F}]"
Run Code Online (Sandbox Code Playgroud)

由于我们匹配的任何代码点都属于Unicode块,因此它也可以写成:

"\\p{InEgyptian_Hieroglyphs}"
"\\p{InEgyptian Hieroglyphs}"
"\\p{InEgyptianHieroglyphs}"

"\\p{block=EgyptianHieroglyphs}"
"\\p{blk=Egyptian Hieroglyphs}"
Run Code Online (Sandbox Code Playgroud)

\p自1.4以来,Java支持Unicode块的语法,但仅在Java 7中添加了对埃及象形文字块的支持.

PCRE(用于PHP)

PHP示例已经包含在georg的答案中:

'~\p{Egyptian_Hieroglyphs}~u'
Run Code Online (Sandbox Code Playgroud)

请注意,u如果要按代码点匹配而不是按代码单元匹配,则必须使用标志.

不确定StackOverflow上是否有更好的帖子,但我已经u在我的这个答案中写了一些关于flag(UTF模式)效果的解释.

需要注意的一件事Egyptian_Hieroglyphs是只能从PCRE 8.02(或不早于PCRE 7.90的版本)获得.

或者,您可以使用\x{h...hh}语法指定字符范围:

'~[\x{13000}-\x{1342F}]~u'
Run Code Online (Sandbox Code Playgroud)

注意强制u标志.

\x{h...hh}至少从PCRE 4.50支持该语法.

JavaScript(ECMAScript)

ES5

georg的答案已经涵盖了字符范围方法(这是在vanilla JavaScript中执行此操作的唯一方法).修改正则表达式以覆盖整个块,包括保留的未分配代码点.

/(?:\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F])/
Run Code Online (Sandbox Code Playgroud)

上面的解决方案演示了匹配星体平面中一系列字符的技术,以及JavaScript RegExp的限制.

JavaScript也遇到与Java相同的字符串表示问题.虽然Java确实Pattern在Java 5中修复了类以允许它使用代码点,但JavaScript RegExp仍然停留在UCS-2时代,迫使我们使用代码单元而不是正则表达式中的代码点.

ES6

最后,在ECMAScript 6中添加了对代码点匹配的支持,ECMAScript 6通过uflag 提供,以防止破坏以前版本的ECMAScript中的现有实现.

从上面的第二个链接检查支持部分,获取为ES6提供实验支持的浏览器列表RegExp.

通过\u{h...hh}在ES6中引入语法,可以用类似于Java 7的方式重写字符范围:

/[\u{13000}-\u{1342F}]/u
Run Code Online (Sandbox Code Playgroud)

或者您也可以直接指定文字中的RegExp字符,但意图不是那么明确[a-z]:

/[-]/u
Run Code Online (Sandbox Code Playgroud)

请注意u上面两个正则表达式中的修饰符.

仍然卡在ES5?别担心,你可以transpile ES6的Unicode正则表达式来ES5正则表达式与regxpu.