Warum kann ich neben einer Wortgrenze keine Zeichen mit Akzent verwenden?

Lesezeit: 21 Minuten

Warum kann ich neben einer Wortgrenze keine Zeichen mit Akzent
Rexxars

Ich versuche, eine dynamische Regex zu erstellen, die mit dem Namen einer Person übereinstimmt. Es funktioniert bei den meisten Namen ohne Probleme, bis ich am Ende des Namens auf akzentuierte Zeichen stieß.

Beispiel: Einige ausgefallene Namen

Die Regex, die ich bisher verwendet habe, ist:

/\b(Fancy Namé|Namé)\b/i

So verwendet:

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

Das passt einfach nicht zusammen. Wenn ich das é durch ae ersetze, passt es gut. Wenn ich versuche, einen Namen wie “Some Fancy Naméa” abzugleichen, funktioniert es einwandfrei. Wenn ich den letzten Wortgrenzanker des Wortes entferne, funktioniert es einwandfrei.

Warum funktioniert das Wort Grenzfahne hier nicht? Irgendwelche Vorschläge, wie ich dieses Problem umgehen könnte?

Ich habe überlegt, so etwas zu verwenden, bin mir aber nicht sicher, wie die Leistungseinbußen aussehen würden:

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

Vorschläge? Ideen?

  • Ich vermute, dass é vielleicht nicht als Wortzeichen (\w) betrachtet wird …

    – Rauben

    15. März 2010 um 19:17 Uhr

Warum kann ich neben einer Wortgrenze keine Zeichen mit Akzent
Bobine

Die Regex-Implementierung von JavaScript ist nicht Unicode-fähig. Es kennt nur die “Wortzeichen” in Standard-Low-Byte-ASCII, die nicht enthalten sind é oder andere akzentuierte oder nicht-englische Buchstaben.

Weil é ist kein Wortzeichen für JS, é gefolgt von einem Leerzeichen kann niemals als Wortgrenze betrachtet werden. (Das würde passen \b wenn es in der Mitte eines Wortes verwendet wird, wie Namés.)

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

Ja, das wäre die übliche Problemumgehung für JS (allerdings wahrscheinlich mit mehr Satzzeichen). Für andere Sprachen würden Sie im Allgemeinen Lookahead/Lookbehind verwenden, um zu vermeiden, dass die Zeichen vor und nach der Grenze übereinstimmen, aber diese werden in JS schlecht unterstützt/fehlerhaft, also am besten vermieden.

  • Das erklärt es. Ich endete mit folgendem: /(\W|^)(fancy namé|name)(\W|$)/ig Was meinen Bedürfnissen zu entsprechen scheint 🙂

    – Rexxars

    16. März 2010 um 9:30 Uhr

Rob hat Recht. Zitiert aus der ECMAScript 3rd Edition:

15.10.2.6 Behauptung:

Die Produktion Behauptung \b bewertet nach …

2. Anruf IsWordChar(e−1) und lass ein sei das boolesche Ergebnis
3. Anruf IsWordChar(e) und lass B sei das boolesche Ergebnis

und

Die interne Hilfsfunktion IsWordChar … führt Folgendes aus:

3. Wenn C eines der dreiundsechzig Zeichen in der folgenden Tabelle ist, return wahr.

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 _

Seit é ist keines dieser 63 Zeichen die Stelle dazwischen é und a wird als Wortgrenze betrachtet.

Wenn Sie die Zeichenklasse kennen, können Sie eine negative Look-Forward-Assertion verwenden, z

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

Warum kann ich neben einer Wortgrenze keine Zeichen mit Akzent
tchrist

Kenne deine Grenzen

Unglücklicherweise, auch wenn Javascript eines Tages volle und angemessene Unterstützung für Unicode haben sollte, werden Sie es tun still müssen mit Wortgrenzen äußerst vorsichtig sein. Es ist leicht zu missverstehen, was a \b wirklich tut.

Hier ist Perl-Code, der erklärt, was \b wirklich tut, was wahr ist, unabhängig davon, ob Ihre Pattern-Engine bereits auf BNM aktualisiert wurde:

  # 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;

Das erste ist wie ein \b vor etwas, und das zweite ist wie a \b Danach. Das verwendete Konstrukt ist die Regex-Bedingung „IF-THEN=ELSE“, die von der allgemeinen Form ist (?(COND)THEN|ELSE). Hier verwende ich a BED test, das ist im ersten Fall ein Lookahead, im zweiten Fall ein Lookahead. Die DANN und ANDERS Klauseln sind in beiden Fällen negierte Lookarounds, sodass sie den Rand der Zeichenfolge berücksichtigen.

Ich erkläre hier mehr über den Umgang mit Grenzen und Unicode in regulären Ausdrücken.

Unterstützung von Unicode-Eigenschaften

Der aktuelle Stand der Dinge im Umgang von Javascript mit Unicode scheint um das wie Java zu sein, die Definitionen von Javascript \w und solche sind noch verkrüppelt, weil man in den 1960er Jahren feststeckte Welt des ASCII. Das ist einfach eine miserable Situation, das gebe ich zu. Sogar Python, das in diesen Dingen ziemlich konservativ ist (es unterstützt zum Beispiel nicht einmal rekursive reguläre Ausdrücke), tut erlauben seine Definitionen von \w und \s korrekt mit Unicode arbeiten. Das ist wirklich das Nötigste an Funktionalität.

Es ist sowohl besser als auch schlechter in Javascript. Das ist wegen dir kann Verwenden Sie einige der grundlegendsten Unicode-Eigenschaften in Javascript (oder Java). Es sieht so aus, als ob Sie in der Lage sein sollten, die ein- und zweistelligen Unicode-Eigenschaften „Allgemeine Kategorie“ zu verwenden. Das bedeutet, dass Sie in der Lage sein sollten, die Kurznamenversionen aus der ersten Spalte unten zu verwenden:

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}

Sie müssen die kurzen Namen nur in Java und Javascript verwenden, aber Perl lässt Sie auch die langen Namen verwenden, was der Lesbarkeit dient. Die Version 5.12 von Perl unterstützt etwa 3.000 Unicode-Eigenschaften. Python still hat keine nennenswerte Unterstützung für Unicode-Eigenschaften, und Ruby fängt gerade an, sie in der Version 1.9 zu bekommen. PCRE hat eine begrenzte Unterstützung, hauptsächlich wie die von Java 1.7.

Java6 unterstützt Unicode-Blockeigenschaften wie \p{InGeneralPunctuation} oder \p{Block=GeneralPunctuation}und Java7 unterstützt Unicode-Skripteigenschaften wie \p{IsHiragana} oder \p{Script=Hiragana}.

Es unterstützt jedoch immer noch nichts, was auch nur annähernd dem entspricht vollständiger Satz von Unicode-Eigenschafteneinschließlich nahezu kritischer wie \p⁠{WhiteSpace}, \p{Dash}und \p{Quotation_Mark}geschweige denn die anderen Zweiteiler mögen \p⁠{Line_Break=Alphabetic}, \p⁠{East_Asian_Width:Narrow}, \p⁠{Numeric_Value=1000}oder \p⁠⁠{Age:5.2}.

Die ersteren Sets sind ziemlich unverzichtbar – insbesondere angesichts der fehlenden Unterstützung für \s funktioniert richtig – und das letztere Set ist manchmal verdammt nützlich.

Etwas anderes, das Java und Javascript noch nicht unterstützen, ist benutzerdefinierte Zeicheneigenschaften. Ich benutze die ziemlich viel. Auf diese Weise können Sie Dinge definieren wie \p⁠{English::Vowel} oder \p⁠{English::Consonant}was ziemlich praktisch ist.

Wenn Sie an Unicode-Eigenschaften für Regex-Arbeiten interessiert sind, sollten Sie sich vielleicht die Einheit Suite von Programmen: Uniprops, uncharsund Uninamen. Hier ist eine Demo von jedem dieser drei:

$ 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 über Unicode-Eigenschaften:

$ 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.1}
       \p{Present_In:3.2} \p{In=3.2} \p{Present_In:4.0} \p{In=4.0} \p{Present_In:4.1} \p{In=4.1} \p{Present_In:5.0} \p{In=5.0} \p{Present_In:5.1} \p{In=5.1} \p{Present_In:5.2} \p{In=5.2} \p{Script:Common} \p{Sc=Zyyy} \p{Script:Zyyy} \p{Sentence_Break:LF} \p{SB=LF} \p{Word_Break:LF}
       \p{WB=LF}

U+0085 ‹U+0085› \N{ NEXT LINE (NEL) }:
    \s \v \R \pC \p{Cc}
    \p{All} \p{Any} \p{Assigned} \p{InLatin1} \p{C} \p{Other} \p{Cc} \p{Cntrl} \p{Common} \p{Zyyy} \p{Control} \p{Pat_WS} \p{Pattern_White_Space} \p{PatWS} \p{Space} \p{SpacePerl} \p{VertSpace} \p{White_Space} \p{WSpace}
    \p{Age:1.1} \p{Bidi_Class:B} \p{Bidi_Class=Paragraph_Separator} \p{Bidi_Class:Paragraph_Separator} \p{Bc=B} \p{Block:Latin_1} \p{Block=Latin_1_Supplement} \p{Block:Latin_1_Supplement} \p{Blk=Latin1} \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:CN} \p{Grapheme_Cluster_Break=Control}
       \p{Grapheme_Cluster_Break:Control} \p{GCB=CN} \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:Next_Line} \p{Lb=NL} \p{Line_Break:NL} \p{Line_Break=Next_Line} \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.1} \p{Present_In:3.2} \p{In=3.2} \p{Present_In:4.0} \p{In=4.0} \p{Present_In:4.1} \p{In=4.1} \p{Present_In:5.0} \p{In=5.0} \p{Present_In:5.1} \p{In=5.1} \p{Present_In:5.2} \p{In=5.2}
       \p{Script:Common} \p{Sc=Zyyy} \p{Script:Zyyy} \p{Sentence_Break:SE} \p{Sentence_Break=Sep} \p{Sentence_Break:Sep} \p{SB=SE} \p{Word_Break:Newline} \p{WB=NL} \p{Word_Break:NL} \p{Word_Break=Newline}

U+03A3 ‹Σ› \N{ GREEK CAPITAL LETTER SIGMA }:
    \w \pL} \p{LC} \p{L_} \p{L&} \p{Lu}
    \p{All} \p{Any} \p{Alnum} \p{Alpha} \p{Alphabetic} \p{Assigned} \p{Greek} \p{Is_Greek} \p{InGreek} \p{Cased} \p{Cased_Letter} \p{LC} \p{Changes_When_Casefolded} \p{CWCF} \p{Changes_When_Casemapped} \p{CWCM} \p{Changes_When_Lowercased} \p{CWL} \p{Changes_When_NFKC_Casefolded}
       \p{CWKCF} \p{Lu} \p{L} \p{Gr_Base} \p{Grapheme_Base} \p{Graph} \p{GrBase} \p{Grek} \p{Greek_And_Coptic} \p{ID_Continue} \p{IDC} \p{ID_Start} \p{IDS} \p{Letter} \p{L_} \p{Uppercase_Letter} \p{Print} \p{Upper} \p{Uppercase} \p{Word} \p{XID_Continue} \p{XIDC} \p{XID_Start}
       \p{XIDS}
    \p{Age:1.1} \p{Bidi_Class:L} \p{Bidi_Class=Left_To_Right} \p{Bidi_Class:Left_To_Right} \p{Bc=L} \p{Block:Greek} \p{Block=Greek_And_Coptic} \p{Block:Greek_And_Coptic} \p{Blk=Greek} \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{Decomposition_Type:None} \p{Dt=None} \p{East_Asian_Width:A} \p{East_Asian_Width=Ambiguous} \p{East_Asian_Width:Ambiguous} \p{Ea=A} \p{Grapheme_Cluster_Break:Other} \p{GCB=XX}
       \p{Grapheme_Cluster_Break:XX} \p{Grapheme_Cluster_Break=Other} \p{Script=Greek} \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:AL} \p{Line_Break=Alphabetic} \p{Line_Break:Alphabetic} \p{Lb=AL} \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.1} \p{Present_In:3.2} \p{In=3.2} \p{Present_In:4.0} \p{In=4.0} \p{Present_In:4.1} \p{In=4.1} \p{Present_In:5.0} \p{In=5.0} \p{Present_In:5.1} \p{In=5.1}
       \p{Present_In:5.2} \p{In=5.2} \p{Script:Greek} \p{Sc=Grek} \p{Script:Grek} \p{Sentence_Break:UP} \p{Sentence_Break=Upper} \p{Sentence_Break:Upper} \p{SB=UP} \p{Word_Break:ALetter} \p{WB=LE} \p{Word_Break:LE} \p{Word_Break=ALetter}

U+221E ‹∞› \N{ INFINITY }:
    \pS \p{Sm}
    \p{All} \p{Any} \p{Assigned} \p{InMathematicalOperators} \p{Common} \p{Zyyy} \p{Sm} \p{S} \p{Gr_Base} \p{Grapheme_Base} \p{Graph} \p{GrBase} \p{Math} \p{Math_Symbol} \p{Pat_Syn} \p{Pattern_Syntax} \p{PatSyn} \p{Print} \p{Symbol}
    \p{Age:1.1} \p{Bidi_Class:ON} \p{Bidi_Class=Other_Neutral} \p{Bidi_Class:Other_Neutral} \p{Bc=ON} \p{Block:Mathematical_Operators} \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:A} \p{East_Asian_Width=Ambiguous} \p{East_Asian_Width:Ambiguous} \p{Ea=A} \p{Grapheme_Cluster_Break:Other} \p{GCB=XX} \p{Grapheme_Cluster_Break:XX}
       \p{Grapheme_Cluster_Break=Other} \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:AI} \p{Line_Break=Ambiguous} \p{Line_Break:Ambiguous} \p{Lb=AI} \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.1} \p{Present_In:3.2} \p{In=3.2} \p{Present_In:4.0} \p{In=4.0} \p{Present_In:4.1} \p{In=4.1} \p{Present_In:5.0} \p{In=5.0} \p{Present_In:5.1} \p{In=5.1} \p{Present_In:5.2} \p{In=5.2} \p{Script:Common} \p{Sc=Zyyy}
       \p{Script:Zyyy} \p{Sentence_Break:Other} \p{SB=XX} \p{Sentence_Break:XX} \p{Sentence_Break=Other} \p{Word_Break:Other} \p{WB=XX} \p{Word_Break:XX} \p{Word_Break=Other}

U+FEFF ‹U+FEFF› \N{ ZERO WIDTH NO-BREAK SPACE }:
    \pC \p{Cf}
    \p{All} \p{Any} \p{Assigned} \p{InArabicPresentationFormsB} \p{C} \p{Other} \p{Case_Ignorable} \p{CI} \p{Cf} \p{Format} \p{Changes_When_NFKC_Casefolded} \p{CWKCF} \p{Common} \p{Zyyy} \p{Default_Ignorable_Code_Point} \p{DI} \p{Graph} \p{Print}
    \p{Age:1.1} \p{Bidi_Class:BN} \p{Bidi_Class=Boundary_Neutral} \p{Bidi_Class:Boundary_Neutral} \p{Bc=BN} \p{Block:Arabic_Presentation_Forms_B} \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:CN} \p{Grapheme_Cluster_Break=Control} \p{Grapheme_Cluster_Break:Control} \p{GCB=CN}
       \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:T} \p{Joining_Type=Transparent} \p{Joining_Type:Transparent} \p{Jt=T}
       \p{Line_Break:WJ} \p{Line_Break=Word_Joiner} \p{Line_Break:Word_Joiner} \p{Lb=WJ} \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.1} \p{Present_In:3.2} \p{In=3.2} \p{Present_In:4.0} \p{In=4.0} \p{Present_In:4.1} \p{In=4.1} \p{Present_In:5.0} \p{In=5.0} \p{Present_In:5.1} \p{In=5.1} \p{Present_In:5.2} \p{In=5.2} \p{Script:Common} \p{Sc=Zyyy} \p{Script:Zyyy}
       \p{Sentence_Break:FO} \p{Sentence_Break=Format} \p{Sentence_Break:Format} \p{SB=FO} \p{Word_Break:FO} \p{Word_Break=Format} \p{Word_Break:Format} \p{WB=FO}

U+3000 ‹U+3000› \N{ IDEOGRAPHIC SPACE }:
    \s \h \pZ \p{Zs}
    \p{All} \p{Any} \p{Assigned} \p{Blank} \p{InCJKSymbolsAndPunctuation} \p{Changes_When_NFKC_Casefolded} \p{CWKCF} \p{Common} \p{Zyyy} \p{Z} \p{Zs} \p{Gr_Base} \p{Grapheme_Base} \p{GrBase} \p{HorizSpace} \p{Print} \p{Separator} \p{Space} \p{Space_Separator} \p{SpacePerl}
       \p{White_Space} \p{WSpace}
    \p{Age:1.1} \p{Bidi_Class:White_Space} \p{Bc=WS} \p{Bidi_Class:WS} \p{Bidi_Class=White_Space} \p{Block:CJK_Symbols_And_Punctuation} \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:Non_Canon} \p{Decomposition_Type=Non_Canonical} \p{Decomposition_Type:Non_Canonical} \p{Dt=NonCanon} \p{Decomposition_Type:Wide} \p{Dt=Wide} \p{East_Asian_Width:F} \p{East_Asian_Width=Fullwidth}
       \p{East_Asian_Width:Fullwidth} \p{Ea=F} \p{Grapheme_Cluster_Break:Other} \p{GCB=XX} \p{Grapheme_Cluster_Break:XX} \p{Grapheme_Cluster_Break=Other} \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:ID} \p{Line_Break=Ideographic} \p{Line_Break:Ideographic} \p{Lb=ID} \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.1} \p{Present_In:3.2} \p{In=3.2} \p{Present_In:4.0} \p{In=4.0} \p{Present_In:4.1}
       \p{In=4.1} \p{Present_In:5.0} \p{In=5.0} \p{Present_In:5.1} \p{In=5.1} \p{Present_In:5.2} \p{In=5.2} \p{Script:Common} \p{Sc=Zyyy} \p{Script:Zyyy} \p{Sentence_Break:Sp} \p{SB=Sp} \p{Word_Break:Other} \p{WB=XX} \p{Word_Break:XX} \p{Word_Break=Other}

U+12345 ‹𒍅› \N{ CUNEIFORM SIGN URU TIMES KI }:
    \w} \p{\pL} \p{L_} \p{Lo}
    \p{All} \p{Any} \p{Alnum} \p{Alpha} \p{Alphabetic} \p{Assigned} \p{InCuneiform} \p{Cuneiform} \p{Is_Cuneiform} \p{Xsux} \p{L} \p{Lo} \p{Gr_Base} \p{Grapheme_Base} \p{Graph} \p{GrBase} \p{ID_Continue} \p{IDC} \p{ID_Start} \p{IDS} \p{Letter} \p{L_} \p{Other_Letter} \p{Print}
       \p{Word} \p{XID_Continue} \p{XIDC} \p{XID_Start} \p{XIDS}
    \p{Age:5.0} \p{Bidi_Class:L} \p{Bidi_Class=Left_To_Right} \p{Bidi_Class:Left_To_Right} \p{Bc=L} \p{Block:Cuneiform} \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=Cuneiform} \p{Block=Cuneiform} \p{Decomposition_Type:None} \p{Dt=None} \p{East_Asian_Width=Neutral} \p{East_Asian_Width:Neutral} \p{Grapheme_Cluster_Break:Other} \p{GCB=XX} \p{Grapheme_Cluster_Break:XX}
       \p{Grapheme_Cluster_Break=Other} \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:AL} \p{Line_Break=Alphabetic} \p{Line_Break:Alphabetic} \p{Lb=AL} \p{Numeric_Type:None} \p{Nt=None} \p{Numeric_Value:NaN} \p{Nv=NaN} \p{Present_In:5.0} \p{In=5.0} \p{Present_In:5.1} \p{In=5.1} \p{Present_In:5.2} \p{In=5.2}
       \p{Script:Cuneiform} \p{Sc=Xsux} \p{Script:Xsux} \p{Sentence_Break:LE} \p{Sentence_Break=OLetter} \p{Sentence_Break:OLetter} \p{SB=LE} \p{Word_Break:ALetter} \p{WB=LE} \p{Word_Break:LE} \p{Word_Break=ALetter}

Oder andersherum:

$ unichars '\pN' '\D' '\p{Latin}'
 Ⅰ      8544  02160  ROMAN NUMERAL ONE
 Ⅱ      8545  02161  ROMAN NUMERAL TWO
 Ⅲ      8546  02162  ROMAN NUMERAL THREE
 Ⅳ      8547  02163  ROMAN NUMERAL FOUR
 Ⅴ      8548  02164  ROMAN NUMERAL FIVE
 Ⅵ      8549  02165  ROMAN NUMERAL SIX
 Ⅶ      8550  02166  ROMAN NUMERAL SEVEN
 Ⅷ      8551  02167  ROMAN NUMERAL EIGHT
 (etc)

$ unichars -a '\pL' '\p{Greek}' 'NFD ne NFKD' 'NAME =~ /SYMBOL/'
 ϐ       976  3D0  GREEK BETA SYMBOL
 ϑ       977  3D1  GREEK THETA SYMBOL
 ϒ       978  3D2  GREEK UPSILON WITH HOOK SYMBOL
 ϓ       979  3D3  GREEK UPSILON WITH ACUTE AND HOOK SYMBOL
 ϔ       980  3D4  GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL
 ϕ       981  3D5  GREEK PHI SYMBOL
 ϖ       982  3D6  GREEK PI SYMBOL
 ϰ      1008  3F0  GREEK KAPPA SYMBOL
 ϱ      1009  3F1  GREEK RHO SYMBOL
 ϲ      1010  3F2  GREEK LUNATE SIGMA SYMBOL
 ϴ      1012  3F4  GREEK CAPITAL THETA SYMBOL
 ϵ      1013  3F5  GREEK LUNATE EPSILON SYMBOL
 Ϲ      1017  3F9  GREEK CAPITAL LUNATE SIGMA SYMBOL

Oh und BNM bedeutet „Schönes neues Jahrtausend“, was sich auf unsere moderne Post-ASCII-Welt bezieht, in der Zeichen mehr als nur sieben winzige Bits breit sind. ☺

Warum kann ich neben einer Wortgrenze keine Zeichen mit Akzent
Josef Swobod

String.replace() akzeptiert die Callback-Funktion als zweiten Parameter. (Ich weiß nicht, warum so viele JS-Tutorials diese nützliche Funktion weglassen.) So können wir unseren eigenen Test für Wortgrenzen schreiben.

Die an anderer Stelle vorgeschlagene Lösung mit regexp /(\W|^)(fancy namé|namé)(\W|$)/iggibt bei Texten wie „nameé“ falsch positive Ergebnisse.

String.prototype.isWordCharAt = function(i) {
    // should work for European languages and Unicode
    return (this.charAt(i) >= 'A' && this.charAt(i) <= 'Z')
        || (this.charAt(i) >= 'a' && this.charAt(i) <= 'z')
        || (this.charCodeAt(i) >= 0xC0 && this.charCodeAt(i) < 0x2000)
    ;
};

"Namé. Goal: Some Fancy Namé. Namé. Nénamé. Namée. Nénamée. Namé"
.replace(/(Namé|Fancy Namé)/ig, function(
match, part1, /* part2, part3, ... */ offset, fullText) {
  // Keep in mind that the number of arguments changes
  // if the number of capturing parenthesis in regexp changes.
  // We could use 'arguments' pseudo-array instead.
  var len1 = part1.length;
  var leftWordBoundary;
  var rightWordBoundary;

  if (offset === 0) {
    leftWordBoundary = fullText.isWordCharAt(offset);
  }
  else {
    leftWordBoundary = (fullText.isWordCharAt(offset - 1)
      != fullText.isWordCharAt(offset));
  }

  if (offset + len1 == fullText.length) {
    rightWordBoundary = fullText.isWordCharAt(offset + len1 - 1);
  }
  else {
    rightWordBoundary = (fullText.isWordCharAt(offset + len1 - 1)
      != fullText.isWordCharAt(offset + len1));
  }

  if (leftWordBoundary && rightWordBoundary) {
    return '<a href="#">' + part1 + '</a>';
  }
  else {
    return part1;
  }
});

Wenn Sie mit “my_word” übereinstimmen möchten, können Sie negatives Hinten verwenden ?<! und negativer Blick nach vorn ?!

Dadurch wird überprüft, dass dem Wort kein Nicht-Wort-Zeichen vorangeht und kein Nicht-Wort-Zeichen folgt
new RegExp(`(?<![A-Za-zÀ-ÖØ-öø-ÿ])my_word(?![A-Za-zÀ-ÖØ-öø-ÿ])`, "gi");

der - steht für Intervall in der ASCII-Tabelle. Hier ist die Ascii-Tabelle, um zu überprüfen, ob es gut ist, was Sie brauchen
http://seamons.com/projects/js/ascii_table.html

1647165910 691 Warum kann ich neben einer Wortgrenze keine Zeichen mit Akzent
Epidemie

Wie andere Antworten bereits betont haben, betrachtet die JS-Regex-Engine “é” nicht als Wortzeichen. Da dies der Fall ist und Sie abgleichen möchten, ob auf diesen Buchstaben ein anderes Nichtwortzeichen folgt, können Sie die verwenden \B Behauptung dort:

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

Wahrscheinlich nicht der beste Code, wenn Sie möchten, dass seine Absicht offensichtlich ist, aber in diesem Fall funktioniert er, hehe.

1647165910 905 Warum kann ich neben einer Wortgrenze keine Zeichen mit Akzent
Zwiebel-Ritter

Versuchen Sie es vielleicht mit der \o oder \x Flags, wenn Sie Ihre Regex verwenden.

Das Ende von diese Referenz für reguläre Javascript-Ausdrücke könnte dir weiterhelfen.

Was die tatsächlichen Oktal- / Hex-Werte betrifft é verbunden ist, bin ich mir nicht sicher.

997090cookie-checkWarum kann ich neben einer Wortgrenze keine Zeichen mit Akzent verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy