Spojrzałem na Stack Overflow ( zastępowanie znaków ... eh , jak JavaScript nie jest zgodny ze standardem Unicode dotyczącym RegExp itp.) I tak naprawdę nie znalazłem konkretnej odpowiedzi na pytanie:
How can JavaScript match for accented characters (those with diacritical marks)?
Zmuszam pole w interfejsie użytkownika, aby pasowało do formatu: last_name, first_name
(najpierw ostatnie [przecinek]) i chcę zapewnić obsługę znaków diakrytycznych, ale najwyraźniej w JavaScript jest to nieco trudniejsze niż w innych językach / platformach.
To była moja oryginalna wersja, dopóki nie chciałem dodać znaków diakrytycznych:
/^[a-zA-Z]+,\s[a-zA-Z]+$/
Obecnie rozważam jedną z trzech metod dodawania wsparcia, z których wszystkie przetestowałem i działam (przynajmniej do pewnego stopnia nie bardzo wiem, jaki jest „zakres” drugiego podejścia). Tutaj są:
Wyraźnie wymieniając wszystkie znaki akcentowane, które chciałbym zaakceptować jako prawidłowe (kiepskie i zbyt skomplikowane):
var accentedCharacters = "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ";
// Build the full regex
var regex = "^[a-zA-Z" + accentedCharacters + "]+,\\s[a-zA-Z" + accentedCharacters + "]+$";
// Create a RegExp from the string version
regexCompiled = new RegExp(regex);
// regexCompiled = /^[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+,\s[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/
- To poprawnie dopasowuje nazwisko / imię do dowolnego z obsługiwanych znaków akcentowanych w
accentedCharacters
.
Moje inne podejście polegało na użyciu .
klasy znaków, aby uzyskać prostsze wyrażenie:
var regex = /^.+,\s.+$/;
- To pasuje do czegokolwiek, co najmniej w formie:
something, something
. To chyba w porządku ...
Ostatnie podejście, które właśnie znalazłem, może być prostsze ...
/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
- Pasuje do wielu znaków Unicode - przetestowanych i działających, chociaż nie próbowałem niczego szalonego, tylko normalne rzeczy, które widzę w naszym dziale językowym dla nazwisk członków wydziału.
Oto moje obawy:
- Pierwsze rozwiązanie jest zbyt ograniczone, a do tego niechlujne i zawiłe. Musiałbym to zmienić, gdybym zapomniał o postaci lub dwóch, a to nie jest zbyt praktyczne.
- Drugie rozwiązanie jest lepsze, zwięzłe, ale prawdopodobnie pasuje znacznie bardziej niż powinno. Nie mogłem znaleźć żadnej prawdziwej dokumentacji na temat tego , co dokładnie
.
pasuje, tylko uogólnienie „dowolnego znaku oprócz znaku nowej linii” (z tabeli w MDN ). Trzecie rozwiązanie wydaje się najbardziej precyzyjne, ale czy są jakieś pułapki? Nie jestem zaznajomiony z Unicode, przynajmniej w praktyce, ale patrząc na tabelę kodów / kontynuację tej tabeli ,
\u00C0-\u017F
wydaje się być całkiem solidna, przynajmniej jak na mój oczekiwany wkład.- Wydział nie będzie przesyłać formularzy z nazwiskami w ich języku ojczystym (np. Arabskim, chińskim, japońskim itp.), Więc nie muszę się martwić o znaki spoza zestawu znaków łacińskich
A więc prawdziwe pytanie (a) : które z tych trzech podejść jest najbardziej odpowiednie do tego zadania? A może są lepsze rozwiązania?
źródło
regex = /^[^,]+,\s[^,]+$/;
aby temu zapobiec..
Odpowiedzi:
Najłatwiejszym sposobem akceptacji wszystkich akcentów jest:
Zobacz https://unicode-table.com/en/, aby znaleźć znaki podane w kolejności numerycznej.
źródło
-
definiuje zakres, a ta technika wykorzystuje kolejność znaków w zestawie znaków w celu zdefiniowania ciągłego zakresu, co zapewnia bardzo zwięzłe rozwiązanie problemuZ
ia
)?Akcentowany zakres łaciński
\u00C0-\u017F
nie był wystarczający dla mojej bazy danych nazw, więc rozszerzyłem wyrażenie regularne doDodałem te bloki kodu (
\u00C0-\u024F
zawiera trzy sąsiednie bloki jednocześnie):\u00C0-\u00FF
Dodatek Latin-1\u0100-\u017F
Rozszerzony łaciński-A\u0180-\u024F
Rozszerzony łaciński B\u1E00-\u1EFF
Rozszerzony łaciński dodatkowyZauważ, że
\u00C0-\u00FF
jest to właściwie tylko część dodatku Latin-1 . Ten zakres pomija niedrukowalne sygnały sterujące i wszystkie symbole z wyjątkiem niezręcznie umieszczonych mnożenia ×\u00D7
i dzielenia ÷\u00F7
.Jeśli potrzebujesz więcej punktów kodowych, możesz znaleźć więcej zakresów na liście znaków Unicode w Wikipedii . Na przykład możesz również dodać Latin Extended-C , D i E , ale pominąłem je, ponieważ teraz tylko historycy wydają się nimi zainteresowani, a zestawy D i E nawet nie renderują się poprawnie w mojej przeglądarce.
Oryginalne wyrażenie regularne zatrzymało
\u017F
się na nazwie „Șenol”. Według analizatora Unicode firmy FontSpace , pierwszy znak to\u0218
ŁACIŃSKIE WIELKIE LITERY S Z PRZECINKIEM PONIŻEJ. (Tak, zwykle zapisuje się to cedilla-S\u015E
, „Şenol”. Ale nie lecę do Turcji, żeby mu powiedzieć: „ Źle wpisujesz swoje imię!”)źródło
[a-zA-Z\u00c0-\u024f\u1e00-\u1eff]
Zależy od zadania :-) Aby dokładnie dopasować wszystkie znaki łacińskie i ich akcentowane wersje, zakresy Unicode prawdopodobnie zapewniają najlepsze rozwiązanie. Można je rozszerzyć na wszystkie znaki niebędące białymi znakami, co można zrobić za pomocą
\S
klasy znaków.Najbardziej podstawowym problemem, jaki tu widzę, nie są znaki diakrytyczne, ale spacje. Jest kilka nazw, które składają się z wielu słów, np. Tytuły. Powinieneś więc wybrać najbardziej ogólne, czyli zezwalać na wszystko oprócz przecinka, który odróżnia imię od nazwiska:
Ale twoje drugie rozwiązanie z
.
klasą znaków jest równie dobre, możesz wtedy tylko zająć się wieloma przecinkami.źródło
any_character_not_a_comma, any_character_not_a_comma
? Tak właśnie pomyślałem, kiedy to przeczytałem po raz pierwszy, trochę się pogubiłem, gdy zobaczyłem tam trzy przecinki.s
białych znaków…[^\s]
do\S
XRegExp Biblioteka posiada wtyczkę o nazwie Unicode , który pomaga rozwiązywać zadania, takie jak ten.
Wspomina się o tym w komentarzach do pytania, ale łatwo go przeoczyć. Zauważyłem to dopiero po udzieleniu tej odpowiedzi.
źródło
anything, anything
.Co powiesz na to?
źródło
Šš
.A co z tym?
Dopasuje każde słowo ze znakami akcentowanymi lub nie.
źródło
z tego wiki: https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin
w przypadku liter łacińskich używam
unika myślników i znaków specjalnych
źródło
Wyjaśnienie:
\pL
- pasuje do każdego rodzaju listu z dowolnego języka\pM
- łączy znak przeznaczony do połączenia z innym znakiem (np. akcenty, umlauty, otaczające pola itp.)\p{Zs}
- dopasowuje biały znak, który jest niewidoczny, ale zajmuje miejsceu
- Ciągi wzorów i tematów są traktowane jako UTF-8W przeciwieństwie do innych proponowanych wyrażeń regularnych (takich jak
[A-Za-zÀ-ÖØ-öø-ÿ]
), będzie to działać ze wszystkimi znakami specyficznymi dla języka, np.Šš
Jest dopasowane przez tę regułę, ale nie jest dopasowane przez inne osoby na tej stronie.Niestety, natywnie JavaScript nie obsługuje tych klas. Możesz jednak użyć
xregexp
npźródło
Możesz usunąć znaki diakrytyczne z alfabetów za pomocą:
Usunie wszystkie znaki diakrytyczne, a następnie wykona na nim Twoje wyrażenie regularne
Odniesienie:
https://thread.engineering/2018-08-29-searching-and-sorting-text-with-diacritical-marks-in-javascript/
źródło