【问题标题】:Why this regex is not working for german words?为什么这个正则表达式不适用于德语单词?
【发布时间】:2011-05-01 21:27:54
【问题描述】:

我正在尝试将以下句子分解成单词并将它们包裹在 span 中。

<p class="german_p big">Das ist ein schönes Armband</p>

我跟着这个: How to get a word under cursor using JavaScript?

$('p').each(function() {
            var $this = $(this);
            $this.html($this.text().replace(/\b(\w+)\b/g, "<span>$1</span>"));
        });

我面临的唯一问题是,在将单词包装成 span 后,生成的 html 是这样的:

<p class="german_p big"><span>Das</span> <span>ist</span> <span>ein</span> <span>sch</span>ö<span>nes</span> <span>Armband</span>.</p>

所以,schönes 分为三个单词 sch、ö 和 nes。为什么会这样?什么可能是正确的正则表达式?

【问题讨论】:

  • 我的猜测是它将奇怪的o 视为一个单独的词。尝试暂时将其更改为普通的o,看看会发生什么。
  • @AdamGaskins:奇怪o :D 。它是O,带有变音符号

标签: javascript jquery regex unicode


【解决方案1】:

\w 仅匹配 A-Z、a-z、0-9 和 _(下划线)。

您可以使用 \S+ 之类的东西来匹配所有非空格字符,包括像 ö 这样的非 ASCII 字符。这可能会或可能不会起作用,具体取决于字符串其余部分的格式。

参考:http://www.javascriptkit.com/javatutors/redev2.shtml

【讨论】:

  • 那最终会是$this.text().replace(/\b(\S+)\b/g, "&lt;span&gt;$1&lt;/span&gt;")
  • 注意:与\w+不同,\S+还会匹配单词末尾的句点、逗号等。因此,如果您使用此正则表达式解析此评论,则第一个匹配项将是“Note:”而不是“Note”。如果这不是你想要的,你需要调整你的正则表达式或执行额外的检查。
【解决方案2】:

\w\b 在 javascript 中不支持 unicode;它们只匹配 ASCII 字/边界字符。如果您的用例都允许在空格上拆分,您可以使用\s/\S,它们可以识别 unicode。

【讨论】:

    【解决方案3】:

    正如其他人所指出的,\w 快捷方式对于非拉丁字符集不是很有用。如果您需要匹配其他文本范围,您应该使用十六进制*表示法 (Ref1) (Ref2) 来匹配适当的范围。

    * 可以是十六进制、八进制或 unicode,您经常会看到这些统称为十六进制表示法

    【讨论】:

      【解决方案4】:

      你也可以使用

      /\b([äöüÄÖÜß\w]+)\b/g
      

      而不是

      /\b(\w+)\b/g
      

      为了处理元音变音

      【讨论】:

        【解决方案5】:

        Javascript Regexen 中的Unicode

        与 Java 本身一样,Javascript 在其 \w\d\b 正则表达式快捷方式中不支持 Unicode。这(可以说)是 Java 和 Javascript 中的一个错误。即使一个人通过诡计或固执地设法争辩说它不是一个错误,这肯定是一个很大的问题。有点咬人,真的。

        问题在于,那些流行的正则表达式快捷方式适用于 Java 或 Javascript 中的 7 位 ASCII。这种限制在 1970 年代是痛苦的;这在 21ˢᵗ 世纪完全没有意义。今年 3 月的 blog posting 为在 Javascript 中解决此问题提供了一个很好的论据。

        真的很好,如果一些热心公益的人愿意将 Javascript 添加到 this Wikipedia page 以比较各种语言的支持正则表达式功能。

        page 表示 Javascript 根本不支持任何 Unicode 属性。同一个站点有a table,这比我上面提到的维基百科页面要详细得多。对于 Javascript 功能,请查看其 ECMA 列。

        但是,在某些情况下,该表至少已过期五年,因此我不能完全担保。不过,这是一个好的开始。

        其他语言的 Unicode 支持

        Ruby、Python、Perl 和 PCRE 都提供了将 \w 扩展为 应该 的含义的方法,但是这两个 J-thingies 没有。

        然而,在 Java 中, 有一个很好的解决方法。在那里,您可以使用 \pL 来表示任何具有 Unicode General_Category=Letter 属性的字符。这意味着您始终可以使用[\pL\p{Nd}_] 模拟正确的\w

        确实,以这种方式编写它甚至有一个优势,因为它让您知道您正在将十进制数字和下划线字符添加到字符类中。使用简单的\w,有时请忘记这是怎么回事。

        不过,我不相信这种解决方法可以在 Javascript 中使用。您还可以使用 Unicode 属性,例如 Perl 和 PCRE 以及 Ruby 1.9 中的那些,但不能在 Python 中使用。

        当前 Java 支持的唯一 Unicode 属性是一字符和二字符的通用属性,如 \pN\p{Lu} 以及像 \p{InAncientSymbols} 这样的块属性,但不支持像 \p{IsGreek} 等脚本。

        未来的 JDK7 最终将开始添加脚本。尽管如此,Java 仍然不支持大多数 Unicode 属性,甚至不支持像 \p{WhiteSpace} 这样的关键属性或像 \p{Dash}\p{Quotation_Mark} 这样方便的属性。

        叹息! 要了解 Java 的属性支持有多么有限,只需将其与 Perl 进行比较即可。 Perl 在 2007 年的 5.10 版本中支持 1633 个 Unicode 属性,在今年的 5.12 版本中支持 2478 个。我还没有将它们计算为古代版本,但 Perl 在上个千年开始支持 Unicode 属性。

        尽管 Java 很蹩脚,但它仍然比 Javascript 好,因为 Javascript 不支持任何 Unicode 属性,例如审查。恐怕Javascript's paltry 7-bit mindset 使它几乎无法用于Unicode。这是语言中一个巨大的漏洞,鉴于其目标域,很难解释。

        对不起。 ☹

        【讨论】:

          【解决方案6】:

          \b 也不能正常工作。可以使用 Xregex 库 \p{L} 标记来支持 unicode,但是仍然不支持 \b,因此您将无法找到单词边界。在下面的实现中通过使用 \P{L} 进行lookbehind/lookaheads 来提供 \b 支持会很好

          http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript

          【讨论】:

            【解决方案7】:

            要包含 all 拉丁语 1 补充字符,例如 äöüßÒÿ,您可以使用:

            [\w\u00C0-\u00ff]
            

            然而,拉丁扩展 A 和拉丁扩展 B unicode 块中还有更多有趣的字符,例如 ČŇů 。要包括您可以使用的内容:

            [\w\u00C0-\u024f]
            

            【讨论】:

            • 这非常适合文本的标记化! var tokens = text.match(/[\w\u00C0-\u00ff]+/g)
            【解决方案8】:

            虽然 javascript 本身不支持 Unicode,但您可以使用这个库来解决它:http://xregexp.com/

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2021-10-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-01-03
              • 2019-04-07
              相关资源
              最近更新 更多