为什么我不能在单词边界旁使用带重音符号?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么我不能在单词边界旁使用带重音符号?相关的知识,希望对你有一定的参考价值。

我正在尝试制作与一个人的名字匹配的动态正则表达式。在大多数名称上都可以正常使用,直到我在名称末尾遇到带重音符号的字符为止。

示例:某些花式Namé

到目前为止,我使用的正则表达式是:

/(Fancy Namé|Namé)/i

像这样使用:

"Goal: Some Fancy Namé. Awesome.".replace(/(Fancy Namé|Namé)/i, '<a href="#">$1</a>');

这根本不匹配。如果将é替换为e,则匹配得很好。如果我尝试匹配“ Some FancyNaméa”之类的名称,则效果很好。如果我删除单词last word边界锚,它就可以正常工作。

为什么单词边界标记在这里不起作用?关于如何解决此问题的任何建议?

我已经考虑使用类似的方法,但是我不确定性能会受到什么样的影响:

"Some fancy namé. Allow me to ellaborate.".replace(/([s.,!?])(fancy namé|namé)([s.,!?]|$)/g, '$1<a href="#">$2</a>$3')

建议?想法?

答案

javascript的regex实现不支持Unicode。它仅知道标准低字节ASCII中的“单词字符”,其中不包含é或任何其他带重音或非英语的字母。

因为é不是JS的文字字符,所以é后面加空格不能被视为文字边界。 (如果用在单词中间,例如,它将与Namés相匹配。)

/([s.,!?])(fancy namé|namé)([s.,!?]|$)/

是的,这将是JS通常的解决方法(尽管可能会有更多的标点符号)。对于其他语言,通常应使用超前/后退以避免与前后边界字符匹配,但是在JS中这些字符受支持不佳/错误,因此最好避免。

另一答案

Rob是正确的。引自ECMAScript第三版:

15.10.2.6断言:

生产断言 的评估依据...

2。调用IsWordChar(e-1)并让a为布尔结果3。调用IsWordChar(e)并让b为布尔结果

内部帮助函数IsWordChar ...执行以下操作:

3。如果c是下表中的六十三个字符之一,则返回true

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 _

由于é不是这63个字符之一,因此éa之间的位置将被视为单词边界。

如果您知道字符的类别,则可以使用否定的前瞻性断言,例如

/(^|[^wÀ-ÖØ-öø-ſ])(Fancy Namé|Namé)(?![wÀ-ÖØ-öø-ſ])/
另一答案

了解您的边界

[不幸的是,即使有一天Javascript应该完全和适当地支持Unicode,您也将[[still在单词边界方面要格外小心。容易误解的实际作用。

这里是解释实际功能的Perl代码,无论您的模式引擎是否已由BNM升级,这都是事实:

# if next is word char: # then last isn't word # else last isn't nonword $word_boundary_before = qr{ (?(?= w ) (?<! w ) | (?<! W ) ) }x; # if last is word: # then next isn't word # else next isn't nonword $word_boundary_after = qr{ (?(?<= w ) (?! w ) | (?! W ) ) }x;

第一个就像在某个东西之前的,第二个就像在它之后的。所使用的构造为条件表达式正则表达式“ IF-THEN = ELSE”,其一般形式为(?(COND)THEN|ELSE)。在这里,我使用的是

COND测试,第一种情况是先行,第二种情况是先行。在两种情况下,THENELSE子句都是否定的环顾四周,因此它们将字符串的边缘考虑在内。

我将解释有关在正则表达式here中处理边界和Unicode的更多信息。

Unicode属性支持

current state of affairs in Javascript’s treatment of Unicode

似乎

就像Java一样,Javascript对w的定义等等仍然由于被卡在1960年代而陷入瘫痪
的ASCII世界。我承认,这只是一个悲惨的情况。甚至Python都非常保守(例如,它甚至不支持递归正则表达式),does允许ws的定义正确地使用Unicode。确实,这是最低的功能级别。在Javasscript中,它既好又坏。这是因为您

can

使用Javascript(或Java)中一些最基本的Unicode属性。看起来您应该能够使用一字符和两个字符的“常规类别” Unicode属性。这意味着您应该能够使用下面第一列中的简称:Short Name Long Name ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ pL p{Letter} p{Lu} p{Uppercase_Letter} p{Ll} p{Lowercase_Letter} p{Lt} p{Titlecase_Letter} p{Lm} p{Modifier_Letter} p{Lo} p{Other_Letter} Short Name Long Name ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ pM p{Mark} p{Mn} p{Nonspacing_Mark} p{Mc} p{Spacing_Mark} p{Me} p{Enclosing_Mark} Short Name Long Name ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ pN p{Number} p{Nd} p{Decimal_Number},p{Digit} p{Nl} p{Letter_Number} p{No} p{Other_Number} Short Name Long Name ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ pP p{Punctuation}, p{Punct}) p{Pc} p{Connector_Punctuation} p{Pd} p{Dash_Punctuation} p{Ps} p{Open_Punctuation} p{Pe} p{Close_Punctuation} p{Pi} p{Initial_Punctuation} p{Pf} p{Final_Punctuation} p{Po} p{Other_Punctuation} Short Name Long Name ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ pS p{Symbol} p{Sm} p{Math_Symbol} p{Sc} p{Currency_Symbol} p{Sk} p{Modifier_Symbol} p{So} p{Other_Symbol} Short Name Long Name ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ pZ p{Separator} p{Zs} p{Space_Separator} p{Zl} p{Line_Separator} p{Zp} p{Paragraph_Separator} Short Name Long Name ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ pC p{Other} p{Cc} p{Control}, p{Cntrl} p{Cf} p{Format} p{Cs} p{Surrogate} p{Co} p{Private_Use} p{Cn} p{Unassigned}
您仅必须在Java和Javascript中使用短名称,但是Perl也允许您使用长名称,这有助于提高可读性,Perl 5.12版本支持大约3,000个Unicode属性。 Python 

still

没有值得一提的Unicode属性支持,而Ruby刚开始在1.9版本中得到它。 PCRE的支持有限,主要是Java 1.7。[Java6支持Unicode块属性,例如p{InGeneralPunctuation}p{Block=GeneralPunctuation},而Java7支持Unicode脚本属性,例如p{IsHiragana}p{Script=Hiragana}

[但是,它仍然不支持甚至接近full set of Unicode properties的任何东西,包括p⁠{WhiteSpace}p{Dash}p{Quotation_Mark}等近临界的东西,更不用说像p⁠{Line_Break=Alphabetic}这样的其他两部分了, p⁠{East_Asian_Width:Narrow}p⁠{Numeric_Value=1000}p⁠⁠{Age:5.2}

[前一组是必不可少的-

尤其是

由于缺乏对s工作正确性的支持,而后一组有时很有用。[Java和Javascript还不支持的其他功能是user-defined character properties。我用了很多。这样,您可以定义p⁠{English::Vowel}p⁠{English::Consonant}之类的东西,这非常方便。

如果您对正则表达式工作的Unicode属性感兴趣,那么tou可能希望获取

unitrio

程序集:unipropsunicharsuninames。这是这三个示例的演示:$ uninames face ፦ 4966 1366 ETHIOPIC PREFACE COLON ⁙ 8281 2059 FIVE DOT PUNCTUATION = Greek pentonkion = quincunx x (die face-5 - 2684) ∯ 8751 222F SURFACE INTEGRAL # 222E 222E ☹ 9785 2639 WHITE FROWNING FACE ☺ 9786 263A WHITE SMILING FACE = have a nice day! ☻ 9787 263B BLACK SMILING FACE ⚀ 9856 2680 DIE FACE-1 ⚁ 9857 2681 DIE FACE-2 ⚂ 9858 2682 DIE FACE-3 ⚃ 9859 2683 DIE FACE-4 ⚄ 9860 2684 DIE FACE-5 ⚅ 9861 2685 DIE FACE-6 ⾯ 12207 2FAF KANGXI RADICAL FACE # 9762 〠 12320 3020 POSTAL MARK FACE 龜 64206 FACE CJK COMPATIBILITY IDEOGRAPH-FACE : 9F9C
FMTEYEWTK关于Unicode属性:

$ uniprops -va LF 85 Greek:Sigma INFINITY BOM U+3000 U+12345 U+000A ‹U+000A› N{ LINE FEED (LF) }: s v R pC p{Cc} p{All} p{Any} p{ASCII} p{Assigned} p{C} p{Other} p{Cc} p{Cntrl} p{Common} p{Zyyy} p{Control} p{Pat_WS} p{Pattern_White_Space} p{PatWS} p{PerlSpace} p{PosixCntrl} p{PosixSpace} p{Space} p{SpacePerl} p{VertSpace} p{White_Space} p{WSpace} p{Age:1.1} p{Block=Basic_Latin} p{Bidi_Class:B} p{Bidi_Class=Paragraph_Separator} p{Bidi_Class:Paragraph_Separator} p{Bc=B} p{Block:ASCII} p{Block:Basic_Latin} p{Blk=ASCII} p{Canonical_Combining_Class:0} p{Canonical_Combining_Class=Not_Reordered} p{Canonical_Combining_Class:Not_Reordered} p{Ccc=NR} p{Canonical_Combining_Class:NR} p{Script=Common} p{Decomposition_Type:None} p{Dt=None} p{East_Asian_Width=Neutral} p{East_Asian_Width:Neutral} p{Grapheme_Cluster_Break:LF} p{GCB=LF} p{Hangul_Syllable_Type:NA} p{Hangul_Syllable_Type=Not_Applicable} p{Hangul_Syllable_Type:Not_Applicable} p{Hst=NA} p{Joining_Group:No_Joining_Group} p{Jg=NoJoiningGroup} p{Joining_Type:Non_Joining} p{Jt=U} p{Joining_Type:U} p{Joining_Type=Non_Joining} p{Line_Break:LF} p{Line_Break=Line_Feed} p{Line_Break:Line_Feed} p{Lb=LF} p{Numeric_Type:None} p{Nt=None} p{Numeric_Value:NaN} p{Nv=NaN} p{Present_In:1.1} p{Age=1.1} p{In=1.1} p{Present_In:2.0} p{In=2.0} p{Present_In:2.1} p{In=2.1} p{Present_In:3.0} p{In=3.0} p{Present_In:3.1} p{In=3

以上是关于为什么我不能在单词边界旁使用带重音符号?的主要内容,如果未能解决你的问题,请参考以下文章

我如何扩展 jquery quicksearch 以便它可以搜索带重音的单词?

MailMessage 带重音符号的附件文件名

R-Shiny 应用程序中的重音符号

正则表达式的与B总结

如何解码 base64 字符串并获取正确的字符,包括重音符号?

如何仅使用 CSS 摆脱重音符号

(c)2006-2024 SYSTEM All Rights Reserved IT常识