2017-04-17 4 views
0

私の意図は、迷惑語を排除し、有用なフレーズの配列を保持することです。 例「メタリカを聞きながらマシュマロを食べたい」 私は言葉を排除したいと思います。 0〜1のように配列を生成ターンウォールドにこれ - 私がpreg_split試み長い文字列をフレーズに分割して配列に格納する正規表現

3-メタリカをリスニングし、各単語を分離マシュマロ 2-食べます| 文字列の最初の単語が正規表現に一致した場合a)は、それがまだ解消されていません。そして私が遭遇し

$arr = preg_split("/ (\bwhere\b)| (\bany\b) |(\bfacebook\b)|(\bthe\b)|(\n)|(\r)|(\r\n)|(,) | (\band\b)| (\bundefined\b) /", $bigString); 

問題は、括弧内の各単語を囲みます。なんらかの理由で、それはまだ文字列に保持され、配列に格納されます。 b)連続した一致が無視されることがあります。例えば。 「私はたくさん食べます」という文字列を入力します。すべての4つの単語が正規表現によってキャッチされるはずですが、単語 'a'は配列にまだ格納されています。

+1

コードを共有してください... – Hossam

+0

問題a):Tあなたの正規表現の冒頭で小さなスペースを削除します。 – Tuyen

答えて

1

2つの問題(aとb)は同じ起源を持ち、パターンの各トークンはスペースで囲まれています。結果:a)トークンの1つが文字列の先頭または末尾にあるときは機能しません。 b)同じスペースを2回一致させることができないため、文字列に連続するトークンがあるときは機能しません。

これらの単語をすべて入れ替えて作成するアプローチは良くありません。パターンのパフォーマンスは、交替に新しいブランチを追加するたびに減少します(最悪の場合は文字列内の各位置正規表現エンジンはすべてのブランチをテストする必要があります)。

これは、文字列を非文字文字(たとえば、空白文字の各シーケンス、および非文字および非空白文字の各シーケンスでより正確に分割すること) 。完了したら、私はarray_diffを使用して、不要な単語を削除します。 array_diffの主な関心事は、キーを保持することです。この方法では、結果配列を生成するためにキーの隙間を見つけるだけで済みます。それはより複雑で長く見えます

場合でも、この方法は、はるかにスケーラブルである:

$str = 'I like to eat marshmallows while also listening to Metallica'; 

$words = [ '', 
      'also', 'and', 'any', 
      'I', 
      'facebook', 
      'the', 'to', 
      'where', 'while' ]; 

$parts = array_diff(preg_split('~(?=\PL)(?:\s+|[^\pL\s]+)~u', $str), $words); 

$previousKey = false; 
$temp = ''; 
$result = []; 

foreach($parts as $k => $v) { 
    if ($previousKey === $k - 1) { 
     $temp .= " $v"; 
    } else { 
     if ($previousKey) 
      $result[] = $temp; 
     $temp = $v; 
    } 
    $previousKey = $k; 
} 

if ($previousKey) 
    $result[] = $temp; 

print_r($result); 

demo

パターンの詳細:

~ 
(?=\PL) # improvement trick: make fail quickly positions with a letter 
     # without to test the whole pattern 
(?: 
    \s+   # any sequence of white-spaces 
    |    # OR 
    [^\pL\s]+ # any sequence of characters that are not letters or white-spaces 
       # 
       # This way: "eat marshmallows" returns: 
       # [0] => eat marshmallows 
       # but: "eat, marshmallows" returns: 
       # [0] => eat 
       # [1] => 
       # [2] => marshmallows 
       # according to your original pattern 
) 
~u # make it able to deal with multibyte utf8 strings 

より良いパターン:~\PL(?(?<=\s)\s*|[^\pL\s]*)~u

+0

ありがとう非常に - 完璧に働いた - あなたは素晴らしいです! :) – Steve

関連する問題