質問

テキストを単語に分割しようとしています:

$delimiterList = array(" ", ".", "-", ",", ";", "_", ":",
           "!", "?", "/", "(", ")", "[", "]", "{", "}", "<", ">", "\r", "\n",
           '"');
$words = mb_split($delimiterList, $string);

これは文字列では非常にうまく機能しますが、数字を使用する必要がある場合には行き詰まります。

E.g。 「これを見てください。私のスコアは3.14で、満足しています。」というテキストがある場合。 これで配列は

[0]=>Look,
[1]=>at,
[2]=>this,
[3]=>My,
[4]=>score,
[5]=>is,
[6]=>3,
[7]=>14,
[8]=>and, ....

その後、3.14は3と14に分割されますが、これは私の場合は発生しません。 つまり、ポイントは2つの文字列を分割する必要がありますが、2つの数字を分割するべきではありません。 次のようになります:

[0]=>Look,
[1]=>at,
[2]=>this,
[3]=>My,
[4]=>score,
[5]=>is,
[6]=>3.14,
[7]=>and, ....

しかし、このケースを回避する方法はわかりません!

この問題を解決する方法はありますか?

ありがとう、 グラニット

役に立ちましたか?

解決

または正規表現を使用:)

<?php
$str = "Look at this.My score is 3.14, and I am happy about it.";

// alternative to handle Marko's example (updated)
// /([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.\-]|[:,.\-](?=\D))/

var_dump(preg_split('/([\s\-_,:;?!\/\(\)\[\]{}<>\r\n"]|(?<!\d)\.(?!\d))/',
                    $str, null, PREG_SPLIT_NO_EMPTY));

array(13) {
  [0]=>
  string(4) "Look"
  [1]=>
  string(2) "at"
  [2]=>
  string(4) "this"
  [3]=>
  string(2) "My"
  [4]=>
  string(5) "score"
  [5]=>
  string(2) "is"
  [6]=>
  string(4) "3.14"
  [7]=>
  string(3) "and"
  [8]=>
  string(1) "I"
  [9]=>
  string(2) "am"
  [10]=>
  string(5) "happy"
  [11]=>
  string(5) "about"
  [12]=>
  string(2) "it"
}

他のヒント

strtok をご覧ください。解析トークンを動的に変更できるため、whileループで文字列を手動で分割し、各分割された単語を配列にプッシュできます。

最初のアイデアは preg_match_all( '/ \ w + /'、$ string、$ matches); でしたが、これはあなたが持っているものと同様の結果をもたらします。問題は、ドットで区切られた数値が非常にあいまいであることです。小数点と文末の両方を意味する可能性があるため、二重の意味を排除するように文字列を変更する方法が必要です。

たとえば、この文には、1つの単語として保持したいいくつかの部分があります:&quot;これを見てください。私のスコアは3.14で、私はそれについて満足しています。 334,3ではなく、今日は2009-12-12 11:12:13ではありません。&quot;

まず検索-&gt;辞書を作成して、例外を分割されないものにエンコードします:

$encode = array(
    '/(\d+?)\.(\d+?)/' => '\\1DOT\\2',
    '/(\d+?),(\d+?)/' => '\\1COMMA\\2',
    '/(\d+?)-(\d+?)-(\d+?) (\d+?):(\d+?):(\d+?)/' => '\\1DASH\\2DASH\\3SPACE\\4COLON\\5COLON\\6'
);

次に、例外をエンコードします:

foreach ($encode as $regex => $repl) {
    $string = preg_replace($regex, $repl, $string);
}

文字列を分割します:

preg_match_all('/\w+/', $string, $matches);

エンコードされた単語を元に戻す:

$decode = array(
    'search' =>  array('DOT', 'COMMA', 'DASH', 'SPACE', 'COLON'),
    'replace' => array('.',   ',',     '-',    ' ',     ':'    )
);
foreach ($matches as $k => $v) {
    $matches[$k] = str_replace($decode['search'], $decode['replace'], $v);
}

$ matches には、正しい例外を使用して単語に分割された元の文が含まれるようになりました。

例外で使用される正規表現を好きなように単純または複雑にすることができますが、いくつかの曖昧さは常に通過します。 >カウントの数は3.3のみとし、3.5以外は何もありません。

&quot;を使用します。 $ delimiterList &quot;。&quot;、の代わりに&quot;、

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top