需要将 unicode 单词列表放入 {} 中的 unicode 字符串中。
有我的代码:
var txt = "¿One;one oneé two two two two two twö twöu three;;twä;föur?";
var re = new RegExp("(^|\\W)(one|tw|two two|two|twöu|three|föur)(?=\\W|$)", "gi");
alert(txt.replace(re, '$1 {$2}'));
它返回:
¿{一};{一} {一}é {二二} {二二} {二} {tw}ö {tw}öu {三};;{tw}ä;{föur}?
但应该是:
¿{一};{一} oneé {二二} {二二} {二} twö {twöu} {三};;twä;{föur}?
我做错了什么?
问题
我究竟做错了什么?
不幸的是,答案是你正在做nothing错误的。 JavaScript 是。
问题是Javascript不支持Unicode 正则表达式 http://www.unicode.org/reports/tr18/如此详细地阐述在统一码标准。
然而,有一个相当不错的库,名为XRegExp http://xregexp.com/其中有一个JavaScript 插件 http://xregexp.com/plugins/这有很大帮助。我推荐它,尽管有几个值得注意的警告。你需要知道它是什么can做什么,以及做什么cannot.
它能做什么
- 纠正了 Javascript 实现中不一致的各种错误,包括its split功能 http://xregexp.com/cross_browser/.
- 支持 2012 年 1 月起 Unicode 字符数据库 6.1 版本所涵盖的 BMP 代码点。
- 正确忽略 Unicode 属性名称中的大小写、空格、连字符和下划线标准——甚至 Java 也会出错。
- 支持 Unicode 常规类别,例如
\p{L}
对于字母和\p{Sc}
对于货币符号。
- 支持标准的完整属性名称,例如
\p{Letter}
for \p{L}
and \p{Currency_Symbol}
for \p{Sc}
.
- 支持 Unicode 脚本属性,例如
\p{Latin}
, \p{Greek}
, and \p{Common}
.
- 支持 Unicode 块属性,例如
\p{InBasic_Latin}
and \p{InMathematical_Alphanumeric_Symbols}
.
- 支持 1 级合规性所需的其他 9 个 Unicode 属性:
\p{Alphabetic}
, \p{Uppercase}
, \p{Lowercase}
, \p{White_Space}
, \p{Noncharacter_Code_Point}
, \p{Default_Ignorable_Code_Point}
, \p{Any}
, \p{ASCII}
, and \p{Assigned}
.
- 支持命名捕获,而不仅仅是编号捕获,使用标准符号来执行此操作:
(?<NAME>⋯)
声明一个命名组,\k<NAME>
按名称反向引用它,然后使用${NAME}
在替换模式中(并且通常使用result.NAME
在你的代码中)。这与 Perl 5.10、Java 7、.ɴᴇᴛ 和其他几种语言使用的语法相同。它允许您命名各个部分而不是仅仅对它们进行编号,从而使编写复杂的正则表达式变得更加容易,这样当您移动内容时就不必重新计算编号的变量。
- 支持
/s
ᴀᴋᴀ (?s)
模式,以便点匹配任何单个代码点,而不是除换行序列之外的任何内容。大多数其他正则表达式引擎都支持此模式。
- 支持
/x
ᴀᴋᴀ (?x)
模式,以便忽略空格和注释(如果未转义)。大多数正则表达式引擎都支持此模式。对于创建清晰且可维护的模式来说,它绝对是必不可少的。
- 即使不在中也支持嵌入注释
/x
使用标准模式(?#⋯)
这样做的符号(例如在 Perl 中看到的)。这使您可以将注释放入各个正则表达式片段中,而无需一路/x
模式,这对于开发更复杂的模式通常很重要,因为它允许您分段构建它们。
- 支持可扩展性,以便您可以根据需要添加新的令牌类型,例如
\a
表示 ALERT 字符或 POSIXish 字符类。
它不做什么
但是,您应该小心它所做的事情not do:
- 不支持完整的 Unicode,但仅支持 Plane 0 中的代码点。这是一个禁止的限制,因为统一码标准要求正则表达式中的星体代码点和非星体代码点之间没有区别。甚至 Java 直到 JDK7 才实现这一点。 (但是,v2.1.0开发版本确实支持完整的Unicode。)
- 不支持
\X
对于字素簇,或者\R
用于换行序列。
- 不支持两部分属性,例如
\p{GC=Letter}
, \p{Block=Phonetic_Extensions}
, \p{Script=Greek}
, \p{Bidi_Class=Right_to_Left}
, \p{Word_Break=A_Letter}
, and \p{Numeric_Value=10}
.
- 它不会更新字符类快捷方式来根据要求进行操作UTS#18 http://www.unicode.org/reports/tr18/#Compatibility_Properties。标准 JavaScript 只允许
\s
以匹配 Unicode\p{White_Space}
财产;它不允许\d
匹配\p{Nd}
(尽管有些旧的浏览器无论如何都会这样做!)也不\w
匹配[\p{Alphabetic}\pM\p{Nd}\p{Pc}]
,更不用说提供 Unicode 感知版本了\b
and \B
,所有这些都是支持 Unicode 正则表达式的要求的一部分。
- 它不支持一些常用的属性。实际上,缺少的是
\p{digit}
,也许还有相当有用的\p{Dash}
, \p{Math}
, \p{Diacritic}
, and \p{Quotation_Mark}
特性。
- 不支持字素簇,例如使用
\X
甚至通过(?:\p{Grapheme_Base}\p{Grapheme_Extend}*)
. 这确实是一件大事。
解决方法
这里有一些解决方法来处理图书馆不遵循的一些地方统一码标准:
- 对于失踪者
\w
, 您可以使用[\p{L}\p{Nl}\p{Nd}\p{M}\p{InEnclosedAlphanumerics}]
。它仅夸大了所附数字中的问题,因为它们并非如此\p{Nd}
- 键入数字,这是唯一算作字母数字的数字。
- 对于失踪者
\W
,因此你可以使用前一个的集补,所以[^\p{L}\p{Nl}\p{Nd}\p{M}\p{InEnclosedAlphanumerics}]
。它仅夸大了所附数字中的问题。
- Since
\b
确实是一样的(?:(?<=\w)(?!\w)|(?<!\w)(?=\w))
, you could插上那个\w
定义到该序列中以创建 Unicode 感知版本\b
——前提是 JavaScript 支持所有四个方向的环视,而当我上次检查时,它不支持。你have为了正确地做到这一点,要同时进行积极和消极的后视,而不仅仅是前视。Javascript 忽略支持那些,至少据我所知。
- Since
\B
确实是一样的(?:(?<=\w)(?=\w)|(?<!\w)(?!\w))
,您可以做同样的事情,但要遵守相同的条件。
- 对于失踪者
\X
,你可以通过使用来接近\P{M}\p{M}*
,但是这错误地分割了 CRLF 结构并允许在相同的结构上进行标记,所有这些都是非常错误的。
- 对于失踪者
\R
,您可以使用构建解决方法(?:\r\n|[\n-\r\u0085\u2028\u2029])
.
Summary
结论是 JavaScript 的正则表达式完全不适合 Unicode 工作。然而,XRegExp 插件 http://xregexp.com/plugins/距离实现这一目标又近了一步。如果您可以忍受它的限制,这可能比切换到其他但支持 Unicode 的编程语言更容易。这当然比根本无法使用 Unicode 正则表达式要好。
然而,距离满足标准中规定的 Unicode 正则表达式最基本的要求(1 级支持)还有相当长的路要走。有一天,您将希望能够匹配字符,无论它们是否带有重音符号,或者在数学字母数字符号块中设置,或者使用 Unicode 大小写映射和大小写折叠定义,或者遵循统一码标准用于字母数字排序或断行和断词,以及你不能做anyJavascript 中的那些东西即使使用插件。
所以你可能希望考虑使用一种语言is符合统一码标准如果你确实需要处理 Unicode。 JavaScript 根本无法做到这一点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)