アクセント付き文字用の具体的なJavascript正規表現(発音区別符号)


166

私はスタックオーバーフロー(文字を置き換える..ええとJavaScriptがどのようにRegExpに関するUnicode標準に準拠していないかなど)を調べましたが、質問に対する具体的な答えは見つかりませんでした。

How can JavaScript match for accented characters (those with diacritical marks)?

UIのフィールドをlast_name, first_name (最後の[カンマスペース]が最初に)一致するように強制していて、発音区別符号のサポートを提供したいのですが、JavaScriptでは、明らかに他の言語/プラットフォームよりも少し難しいです。

これは、発音区別符のサポートを追加するまで、元のバージョンでした。

/^[a-zA-Z]+,\s[a-zA-Z]+$/

現在、サポートを追加するための3つの方法の1つについて議論しています。それらはすべてテストして動作しました(少なくともある程度は、2番目のアプローチの「範囲」が何であるか本当にわかりません)。はい、どうぞ:

有効にしたいすべてのアクセント付き文字を明示的にリストします(不完全で複雑すぎる)。


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àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/
  • これは、姓/名とサポートされているアクセント付き文字のいずれかとを正しく一致させaccentedCharactersます。

私のもう1つのアプローチは、.文字クラスを使用して、より単純な式にすることでした。

var regex = /^.+,\s.+$/;
  • これは、少なくとも次の形式で、ほぼすべてに一致しますsomething, something。それは大丈夫だと思います...

私が見つけた最後のアプローチはもっと簡単かもしれません...

/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
  • これは、Unicodeのさまざまな文字に一致します。テストして機能しましたが、クレイジーなことは何もしませんでした。

ここに私の懸念があります:

  1. 最初のソリューションは制限が多すぎ、ずさんで複雑です。1、2文字を忘れた場合は変更する必要がありますが、それはあまり実用的ではありません。
  2. 2番目のソリューションの方が簡潔ですが、実際よりもはるかに一致する可能性があります。正確に.一致するものに関する実際のドキュメントは見つかりませんでした。「改行文字を除くすべての文字」の一般化(MDNの表から)だけです。
  3. 3番目の解決策が最も正確なようですが、問題点はありますか?私は、少なくとも、実際には、Unicodeを使用した非常に慣れていないんだけど、見て、コード表 / そのテーブルの継続\u00C0-\u017F少なくとも私の予想入力のために、かなり固体であるように思われます。

    • 教員は、母国語(例:アラビア語、中国語、日本語など)で名前が記載されたフォームを送信しないため、ラテン文字以外の文字セットの文字について心配する必要はありません。

だから本当の質問:これらの3つのアプローチのうちどれがタスクに最も適していますか?または、より良い解決策はありますか?


1
より複雑な正規表現を使用する特別な理由はないようです。最も単純なソリューションの唯一のことは、「何か、何か、何か」にも一致することです。あなたはそれregex = /^[^,]+,\s[^,]+$/;を防ぐようなものを使うことができます。
usr2564301 2013

4
一見すると、最初の名前は一般名の「O'Donnell、Chris」とは一致せず、姓とハイフンを組み合わせたものや複数の姓なども一致しません。考えられるすべての落とし穴については、プログラマーが名前について信じる虚偽を参照してください。
usr2564301 2013

原子以外のものと一致する改行を実際には非常に正確である:-)」.
Bergi

1
追加のライブラリを使用することが可能である場合は、ここ
stea

ジョンウェア、私は実際に私の質問への答えを探してSOを閲覧しているときにその記事を読んだだけです-ハイフンやアポストロフィなどについても完全に忘れてしまいました。最初に国際化することにもっと関心を持っていました:Pでも!そしてStema、私は実際にそのライブラリを見て、これはすべてGoogle Apps Scriptにあるため、ライブラリの組み込みを避けます-外部ライブラリを組み込むことは悪夢であり、特定の1つのフィールドに対してのみ(この場合)使用します...やり過ぎの種類:P
Chris Cirefice '19

回答:


274

すべてのアクセントを受け入れる簡単な方法は次のとおりです。

[A-zÀ-ú] // accepts lowercase and uppercase characters
[A-zÀ-ÿ] // as above but including letters with an umlaut (includes [ ] ^ \ × ÷)
[A-Za-zÀ-ÿ] // as above but not including [ ] ^ \
[A-Za-zÀ-ÖØ-öø-ÿ] // as above but not including [ ] ^ \ × ÷

番号順にリストされている文字については、https://unicode-table.com/en/を参照してください


2
+1でもうまく機能しますが、なぜ機能するのか詳しく説明してください。
Pierre Henry

1
@PierreHenryは-範囲を定義します。この手法では、文字セット内の文字の順序を利用して連続範囲を定義し、問題を非常に簡潔に解決します
Angad

8
しません。この試合のアンダースコア(との間に他の非単語文字Za)?
jcuenod

21
これは少なくとも[、]、^、および\の文字に一致しますが、これらの文字を含めることはできません。
2016

2
働いていない、この範囲内の数文字がアクセント付き文字ではありません(U + 00D7は、例えば乗算記号である)、この参照:unicode-table.com/en
ジェレミーPouyet

39

アクセント付きラテン語の範囲\u00C0-\u017Fは、私の名前のデータベースには十分ではなかったため、正規表現を

[a-zA-Z\u00C0-\u024F]
[a-zA-Z\u00C0-\u024F\u1E00-\u1EFF] // includes even more Latin chars

これらのコードブロックを追加しました(\u00C0-\u024F隣接する3つのブロックを同時に含みます)。

これ\u00C0-\u00FFは実際にはLatin-1 Supplementの一部にすぎないことに注意してください。その範囲は、印刷できない制御信号と、ぎこちなく配置された乗算× \u00D7と除算exceptを除くすべてのシンボルをスキップします\u00F7

[a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u024F] // exclude ×÷

さらにコードポイントが必要な場合は、ウィキペディアのUnicode文字リストでより多くの範囲を見つけることができます。たとえば、Latin Extended-CD、およびEを追加することもできますが、今は歴史家だけが興味を持っており、DおよびEセットがブラウザーで正しく表示されないため、省略しました。

元の正規表現\u017Fは、「Șenol」という名前で停止しました。FontSpaceのUnicodeアナライザーによると、その最初の文字は\u0218、ラテン文字の大文字のS と以下のカンマです。(そうです、通常はセディーユSの\u015E「Şenol」とつづられていますが、トルコに飛んで「あなたの名前のつづりが間違っている!」と言っているわけではありません。)


1
ユニコードテーブルのラテン語ブロックを見て、\ u1e00- \ u1effも含める必要があると思うので、実行しています[a-zA-Z\u00c0-\u024f\u1e00-\u1eff]
cprcrack

18

これらの3つのアプローチのどれがタスクに最も適していますか?

タスクに依存:-)すべてのラテン文字とそのアクセント付きバージョンを正確に一致させるには、Unicode範囲がおそらく最良の解決策を提供します。それらは、空白以外のすべての文字に拡張される場合があります。これは、\S文字クラスを使用して実行できます。

UIのフィールドを次の形式に一致させます:(last_name, first_name最後の[カンマスペース]最初)

ここで私が目にする最も基本的な問題は、発音区別符号ではなく空白です。タイトルなど、複数の単語で構成される名前がいくつかあります。したがって、最も一般的なものを使用する必要があります。つまり、姓と名を区別するカンマ以外のすべてを許可します。

/[^,]+,\s[^,]+/

しかし、.文字クラスを使用した2番目のソリューションも同様に問題なく、複数のカンマを気にする必要があるだけかもしれません。


ええと、多分あなたは正しいです。多分それを複雑にしすぎた...あなたが提供した正規表現を説明してもらえますか?私はしばらくの間正規表現を使用してきましたが、基本的なものだけであり、実際にはあなたが実際に行うことの手がかりはありません!ハ
クリスチレフィス

これは否定された文字クラスであり、「コンマ以外のもの」を意味します。
Bergi

ああ、それはもっと読むany_character_not_a_comma, any_character_not_a_comma?それを最初に読んだときにそれが思ったのですが、そこに3つのカンマがあったので、ちょっと混乱しました。
Chris Cirefice 2013

はい、正確に。sホワイトスペースの欠落との混乱でごめんなさい…
Bergi

1
MateoTibaquirá@あなたは簡素化することができます[^\s]\S
Bergi

15

XRegExpのライブラリがありユニコードという名前のプラグインがこのようなタスクを解決するのに役立ちます。

<script src="xregexp.js"></script>
<script src="addons/unicode/unicode-base.js"></script>
<script>
  var unicodeWord = XRegExp("^\\p{L}+$");

  unicodeWord.test("Русский"); // true
  unicodeWord.test("日本語"); // true
  unicodeWord.test("العربية"); // true
</script>

それは質問へのコメントで言及されていますが、見落としがちです。この回答を提出して初めて気づきました。


いいですね、実際にはunicodeで正規表現する必要はなく、パターンで正規表現する必要がありましたanything, anything。これは、将来の読者に役立ちます:)
Chris Cirefice


5

これはどうですか?

^([a-zA-Z]|[à-ú]|[À-Ú])+$

アクセント付き文字の有無にかかわらず、すべての単語に一致します。


2
しかし、OPはアクセント付き文字を許可したいと考えています
barbsan 2018


3
/^[\pL\pM\p{Zs}.-]+$/u

説明:

  • \pL -あらゆる言語のあらゆる種類の手紙に一致
  • \pM -別の文字と組み合わせることが意図されている文字をアクセントします(アクセント、ウムラウト、囲みボックスなど)。
  • \p{Zs} -非表示の空白文字に一致しますが、スペースを占有します
  • u -パターンと件名の文字列はUTF-8として扱われます

他の提案されている正規表現(など[A-Za-zÀ-ÖØ-öø-ÿ])とは異なり、これはすべての言語固有の文字で機能します。たとえばŠš、このルールでは一致しますが、このページの他の文字では一致しません。

残念ながら、JavaScriptは本来これらのクラスをサポートしていません。ただし、xregexpたとえば、

const XRegExp = require('xregexp');

const isInputRealHumanName = (input: string): boolean => {
  return XRegExp('^[\\pL\\pM-]+ [\\pL\\pM-]+$', 'u').test(input);
};

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.