4

コードは次のとおりです。

BanglaAlphabet = {
    'Consonant'                   : '[\u0995-\u09B9\u09CE\u09DC-\u09DF]',
    'IndependantVowel'            : '[\u0985-\u0994]',
    'DependantVowel'              : '[\u09BE-\u09CC\u09D7]',
    'Nukta'                       : '[\u09BC]'
}
BanglaWordPattern = ur"""(
    ({DependantVowel}{Nukta}{Consonant}) |
    ({DependantVowel}{Consonant}) |
    {IndependantVowel} |
    {Consonant} |
)+""".format(**BanglaAlphabet)
BanglaWordPattern = re.compile(BanglaWordPattern, re.VERBOSE)

マッチングは以下で行われます:

re.match(BanglaWordPattern, w[::-1])

これは、右から左に一致する場合に有効なベンガル語に一致することを意味します。

ただし、োগাড় や িদগ などの無効な単語に一致しています。

何が問題なのですか?

編集

@GarethRees と @ChrisMorgan によって提案された多数の修正の後、最終的には次のようになりました。

bangla_alphabet = dict(
    consonant         = u'[\u0995-\u09b9\u09ce\u09dc-\u09df]',
    independent_vowel = u'[\u0985-\u0994]',
    dependent_vowel   = u'[\u09be-\u09cc\u09d7]',
    dependent_sign    = u'[\u0981-\u0983\u09cd]',
    virama            = u'[\u09cd]'
)
bangla_word_pattern = re.compile(ur'''(?:
    {consonant}
    ({virama}{consonant})?
    ({virama}{consonant})?
    {dependent_vowel}?
    {dependent_sign}?
    |
    {independent_vowel}
    {dependent_sign}?
)+

マッチングは次のとおりです。

bangla_word_pattern.match(w)

このコードは、エラーを修正するだけでなく、以前よりも多くの文字と有効な構造を考慮しています。

期待どおりに機能していることを報告できてうれしいです。そのため、このコードは現在、ベンガル語の構文を検証するための非常に基本的な正規表現として機能しています。

実装されていない特別なルール/例外がいくつかあります。それらを調べて、この基本構造に徐々に追加していきます。

多くの ''.format(**bangla_alphabet), re.VERBOSE)

マッチングは次のとおりです。

xCodexBlockxPlacexHolderx

このコードは、エラーを修正するだけでなく、以前よりも多くの文字と有効な構造を考慮しています。

期待どおりに機能していることを報告できてうれしいです。そのため、このコードは現在、ベンガル語の構文を検証するための非常に基本的な正規表現として機能しています。

実装されていない特別なルール/例外がいくつかあります。それらを調べて、この基本構造に徐々に追加していきます。

4

2 に答える 2

3

文字列কয়াは次の文字で構成されています。

>>> import unicodedata
>>> map(unicodedata.name, u'কয়া')
['BENGALI LETTER KA', 'BENGALI LETTER YA', 'BENGALI SIGN NUKTA', 'BENGALI VOWEL SIGN AA']

U + 09BC BENGALISIGNNUKTAは正規表現と一致しません。

ベンガル語のコードチャートを見ると、他の文字を見逃している可能性があります。


OK、更新された質問に答えます。あなたは3つの間違いを犯しています:

  1. BanglaAlphabet辞書の文字列にu(Unicode)フラグがありません。これは、のようなUnicodeエスケープシーケンス\u0995がUnicode文字に変換されていないことを意味します。バックスラッシュ、文字、数字を取得するだけです。

  2. 正規表現では、末尾近くにBanglaWordPattern縦棒があり、その後には何もありません。|つまり、正規表現全体がのようになり(stuff1|stuff2|stuff3|stuff4|)+ます。したがって、実際には5つの選択肢があり、最後の選択肢は空です。もちろん、空の正規表現は何にでも一致します。

  3. プログラムの結果を実際に見て、実際に何が一致したかを確認しているわけではありません。書くm = re.match(BanglaWordPattern, w[::-1]); print m.group(0)と、実際に一致したのは空の文字列であることがわかります。

以下も間違いだと思いますが、何をしようとしているのか説明していないので、自信がありません。

  1. あなたは逆に試合をしている、それは不必要である。パターンを回転させて前方に一致させると、より簡単で理解しやすくなります。

  2. 正規表現でキャプチャ括弧を使用しています。結果が必要ない場合は、(?:...)代わりにキャプチャしない括弧を使用してください。

  3. とにかく、括弧の内側のセットは不要です。

  4. 正規表現の終わりを単語の境界または文字列の終わりに固定していません。

私はこのようなものを書くでしょう:

import re

bangla_categories = dict(
    consonant         = u'[\u0995-\u09B9\u09CE\u09DC-\u09DF]',
    independent_vowel = u'[\u0985-\u0994]',
    dependent_vowel   = u'[\u09BE-\u09CC\u09D7]',
    nukta             = u'[\u09BC]',
)

bangla_word_re = re.compile(ur"""(?:
    {consonant}{nukta}{dependent_vowel} |
    {consonant}{dependent_vowel} |
    {independent_vowel} |
    {consonant}
)+(?:\b|$)""".format(**bangla_categories), re.VERBOSE)

しかし、私はあなたが省略したコードチャートの他のバングラ記号も見ていきます。U + 0981 BENGALISIGNCANDRABINDUとU+0982 BENGALI SIGN ANUSVARA(母音を鼻音化する)はどうですか?U + 09CD BENGALI SIGN VIRAMA(母音をキャンセルする)はどうですか?等々。

于 2012-04-17T11:56:58.833 に答える
1

あなたが持っているものにはいくつかの問題があります:

  • Unicode 文字列ではないため、正規表現にはリテラルなどが含まれてしまい\u0995ます。実際の Unicode 文字を含める必要があります。

  • $文字列全体のみに一致するように、正規表現の最後に必要です。

  • グループに有効な空の文字列がありました(最初のグループをパイプで終了し、空のオプションを残します)。$これは、シンボルの欠如と相まって、機能しないことを意味していました。

  • それは完全ではありません (Gareth の観察によると)。

また、コンパイルされた正規表現オブジェクトを取得したら、bengali_word_pattern.match(s)代わりに行うこともできることに注意してください。re.match(bengali_word_pattern, s)

bengali_alphabet = {
    'consonant': u'[\u0995-\u09B9\u09CE\u09DC-\u09DF]',
    'independent_vowel': u'[\u0985-\u0994]',
    'dependent_vowel': u'[\u09BE-\u09CC\u09D7]',
    'nukta': u'\u09BC'
}

bengali_word_pattern = ur'''^(?:
    (?:{dependent_vowel}{nukta}{consonant}) |
    (?:{dependent_vowel}{consonant}) |
    {independent_vowel} |
    {consonant}
)+$'''.format(**bengali_alphabet)
bengali_word_pattern = re.compile(bengali_word_pattern, re.VERBOSE)

今、

>>> bengali_word_pattern.match(u'বাংলা'[::-1])

これは、「ং」文字 U+0982 のために機能しません。それはあなたの範囲のどれにもありません。そのビットがオフハンドに分類されるカテゴリがわからない。問題のあるキャラクターを取り除くだけで機能します。(Google 翻訳は、結果の単語は「ブレスレット」に翻訳できると教えてくれました—わかりません。妹に尋ねる必要があります。正直に言うと、ほぼすべて、আমি বাংলা বলতে পারি নাです。私が知っていることのほとんどは、便利なものです。 মুরগি চোর のような日常的なフレーズ. そして、その最初の単語には、これまでに見逃した母音も含まれています. とにかく、それは重要ではありません.

>>> bengali_word_pattern.match(u'বালা')
<_sre.SRE_Match object at 0x7f00f5bf9620>

「鶏泥棒」のフレーズにも効きます。

>>> [bengali_word_pattern.match(w[::-1]) for w in u'মুরগি চোর'.split()]
[<_sre.SRE_Match object at 0x7f00f5bf9620>, <_sre.SRE_Match object at 0x7f00f5bf97e8>]

そして、これら 2 つの不完全な単語の例には一致しません。

>>> bengali_word_pattern.match(u'োগাড়'[::-1])
>>> bengali_word_pattern.match(u'িদগ'[::-1])

また、この時点で、なぜ文字列を逆方向に解析しているのかについて当惑していることを認めます。順方向に実行するのが理にかなっていると思いました(この正規表現は正しく機能するため、使用する必要はありません[::-1]):

^(?:
    {consonant}
    (?:
        {nukta}?
        {dependent_vowel}
    )?
    |
    {independent_vowel}
)+$

各接続詞/文字で、独立母音または子音の後に従属母音が続く可能性があり、それらの間に nukta がある可能性があります。

私が行った他の変更:

  • 標準の Python コーディング スタイルに適合する変数/アイテムの命名。
  • (...)パフォーマンスのために(一致するグループ) を (一致しないグループ)に置き換えました ((?:...)ドキュメントを参照)。
  • 「従属」の綴りを修正。
  • 英語ではベンガル語なので、「バングラ」を「ベンガル語」に変更しました。英語を話すときは、母国語の発音よりも言語の標準的な英語名を使用することを好みます。必要に応じて英語化します。一方で、ベンガル語は英語を話す人から定期的にバングラと呼ばれていることも知っています。
于 2012-04-17T14:37:04.643 に答える