1

ラテン語/表意文字 (中国語/日本語/韓国語) が混在する全文検索のために、正規表現を使用して一部の入力をサニタイズ/フォーマットしようとしています。

フォーラムでラテン語/アジア語の文字列をサニタイズしようとする誰かの試みの古い例を見つけましたが、これは二度と見つけることができません (このコードの元の作成者への完全なクレジット)。

関数の正規表現部分を完全に理解するのに苦労しています。特に、数字0、2、および3をラテン語ベースの数字1,4-9とは異なる方法で扱っているようです(基本的に数字0、 4-9 は適切に処理されますが、クエリ内の数字 0、2-3 はアジア文字として扱われます)。

例えば。次の文字列をサニタイズしようとしています:
"hello 1234567890 引き取った abc123def"

「hello 1 456789
abc1 def 2 3 0 蓄積した 2 3」

このサニタイズされた文字列の正しい出力は次のようになります:
"hello 1234567890 蓄積した abc123def"

ご覧のとおり、アジア文字のスペースは適切に配置されていますが、数字 0、2、3 は他のすべての数字とは異なる方法で処理されています。正規表現がこれらの数値 0、2、および 3 を異なる方法で処理する理由についてのヘルプは、大きな助けになります (または、同様の結果を達成するためのより良い方法を知っている場合)! ありがとうございました

以下の関数を含めました

関数 prepareString($str) {
$str = mb_strtolower(trim(preg_replace('#[^\p{L}\p{Nd}\.]+#u', ' ', $str)));

return trim(preg_replace('#\s\s+#u', ' ', preg_replace('#([^\12544-\65519])#u', ' ', $str) . ' . implode(' ' , preg_split('#([\12544-\65519\s])?#u', $str, -1, PREG_SPLIT_NO_EMPTY))));
}

更新: 明確にするためにコンテキストを提供する

中国で立ち上げ予定のウェブサイトをオーサリングしています。この Web サイトには検索機能があり、検索クエリ入力用のパーサーを作成しようとしています。

文中の単語間の区切り文字として " " を使用する英語とは異なり、中国語では単語間にスペースを使用しません。このため、各漢字を分解し、データベース内で各文字を個別に検索して、検索クエリを再フォーマットする必要があります。中国のユーザーは、中国語の文字と組み合わせることができるブランド名などにラテン語/英語の文字も使用します (例: Ivy牛仔舖)。

私がやりたいのは、すべての英単語を漢字から切り離し、各漢字をスペースで区切ることです。

検索クエリは次のようになります: Ivy牛仔舖</p>

そして、次のように解析したいと思います: Ivy 牛 仔 舖</p>

4

3 に答える 3

1

私は PHP と中国語のどちらも扱えるように設定されていないため、明確な回答を提供することはできませんが、少なくとも質問を絞り込むのに役立つはずです。私が見ているように、それは基本的に 4 つのステップのプロセスです。

  • 句読点などの望ましくない文字を取り除き、空白に置き換えます

  • 空白の正規化: 先頭と末尾のスペースを取り除き、2 つ以上のスペースを 1 つのスペースにまとめます

  • 大文字と小文字を正規化: 大文字を対応する小文字に置き換えます

  • 漢字が別の非空白文字の隣にある場合は、2 つの文字をスペースで区切ります

最初の 3 つの手順については、投稿したコードの最初の行で十分です。

$str = mb_strtolower(trim(preg_replace('#[^\p{L}\p{Nd}\.]+#u', ' ', $str)));

最後のステップとして、ルックアラウンドをお勧めします。

$str = preg_replace(
    '#(?<=\S)(?=\p{Chinese})|(?<=\p{Chinese})(?=\S)#u',
    ' ', $str);

次の文字が中国語で前の文字が空白でない、またはの文字が中国語で次の文字が空白でない任意の位置にスペースを挿入する必要があります。

于 2009-07-07T21:55:46.963 に答える
1

問題は正規表現にあるよう[^\12544-\65519]です。これは、2 つの 5 桁の 8 進エスケープによって定義される範囲のように見えますが、そのようには機能しません。実際の内訳は次のようになります。

\125 => octal escape for 'U'
4    => '4'
4    => '4'
-
\655 => octal escape for... (something)
1    => '1'
9    => '9'

これは実質的に次と同じです。

[^14-\655]

範囲の上限が何\655を意味するのかは明確ではありませんが、文字クラスは「1」、「4」、または「4」よりも高いコード ポイントを持つ任意の ASCII 文字 (「9」と「 「う」)。ただし、それは問題ではありません。重要な点は、8 進エスケープには最大 3 桁を含めることができるため、ニーズには適さないということです。\x{nnn}代わりに、PHP の 16 進数表記を使用することをお勧めします。

于 2009-07-05T01:08:31.433 に答える
0

さらなる調査とAlanのコメントの助けを借りて、私は正しい正規表現の組み合わせを見つけて、満足している表意文字と表意文字(中国語/日本語)を分離するためのクエリ解析機能を実現することができました。

関数prepareString($ str){
    $ str = mb_strtolower(trim(preg_replace('#[^ \ p {L} \ p {Nd}] +#u'、''、$ str)));
    return trim(preg_replace('#\ s \ s +#u'、''、preg_replace('#\ p {Han} #u'、''、$ str)。'' .implode(''、preg_split('# \ P {Han}?#u'、$ str、-1、PREG_SPLIT_NO_EMPTY))));
}

$ query="米娜Mi-NaNa日系時尚館╭☆旅行渡假風格【A6402】korea拼接條紋口袋飛鼠棉」

echo prepareString($ query); // "mi nanaa6402korea米娜日系時尚館旅行渡假風格拼接條紋口袋飛鼠棉"

免責事項:私は北京語を読むことができず、上記の文字列は中国のウェブサイトからコピーされました。不快なことがあれば教えてください。削除します。

于 2009-07-07T23:51:16.760 に答える