【问题标题】:Regex to match Egyptian Hieroglyphics [closed]正则表达式匹配埃及象形文字[关闭]
【发布时间】:2015-05-07 21:54:46
【问题描述】:

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

我无法发布这些字母,因为堆栈溢出似乎无法识别它。

那么谁能告诉我这些字符的 unicode 范围。

【问题讨论】:

  • 这显然是关于编程的,任何人都可以从两个充满编程内容的优秀答案中看出!投票重新开放。

标签: regex unicode internationalization


【解决方案1】:

Unicode 在 U+13000 到 U+1342F 的范围内编码 Egyptian hieroglyphs(超出基本多语言平面)。

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

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

    虽然在正则表达式中为 BMP 中的字符指定字符范围就像 [a-z] 一样简单,但取决于语言支持,为星体平面中的字符执行此操作可能不那么简单。

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

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

Java

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

Sun/Oracle 实施

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

由于 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的字符范围,所以我只在这里包含代码。它还包括一些错误尝试编写正则表达式以匹配星体平面字符的反例。

Java 5(及以上)

"[\uD80C\uDC00-\uD80D\uDC2F]"

Java 7(及以上)

"[\\uD80C\\uDC00-\\uD80D\\uDC2F]"
"[\\x{13000}-\\x{1342F}]"

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

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

"\\p{block=EgyptianHieroglyphs}"
"\\p{blk=Egyptian Hieroglyphs}"

Java 从 1.4 开始支持 Unicode 块的 \p 语法,但仅在 Java 7 中添加了对埃及象形文字块的支持。

PCRE(用于 PHP)

georg's answer 中已经介绍了 PHP 示例:

'~\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} 语法。

JavaScript (ECMAScript)

ES5

georg's answer 已经介绍了字符范围方法(这是原生 JavaScript 中唯一的方法)。正则表达式稍作修改以覆盖整个块,包括保留的未分配代码点。

/(?:\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F])/

上面的解决方案演示了匹配星界中一系列字符的技术,以及 JavaScript RegExp 的局限性。

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

ES6

最后,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。

【讨论】:

    【解决方案2】:

    TLDNR:\p{Egyptian_Hieroglyphs}

    Javascript

    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 的平台上,您可以直接使用埃及代码点 130001342F,但语法因系统而异。例如,在 Python(3.3 以上)中,它将是 [\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] => ?
        )
    

    【讨论】:

      猜你喜欢
      • 2013-04-16
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 2013-07-08
      • 1970-01-01
      • 1970-01-01
      • 2017-04-06
      相关资源
      最近更新 更多