2012-03-03 11 views
1

リマインダーをデータベースに簡単に追加する方法として、ツイートを解析しています。つぶやきは次のようになります:正規表現が一致しないデータを取得するにはどうすればよいですか?

$tweet = '#notes @username !high_priority [Project Name] Tweet content'; 

私は、次の正規表現を使って#、@、!そして、[プロジェクト]

$match = preg_match_all('/(#\\w*[a-zA-Z_]+\\w*)|(!\\w*[a-zA-Z_]+\\w*)|(@\\w*[a-zA-Z_]+\\w*)|(\\[[^\\]]*\\])/i', 
    $tweet, 
    $matches); 

私はまた、残りの「ツイートの内容を」取得する方法を知りたいので、正規表現にマッチdoes'tすべてが変数に保存する必要があります。また

、意志のつぶやきは、よりのようなものであればマッチ順事項:

$tweet = '@username Tweet content [Project Name] #notes !high_priority'; 

誰もがそれを行う方法を知っていますか?

+1

「\ w」とは何と思いますか? '[a-zA-Z]'とほぼ同じです – Vyktor

+0

マッチをループして、#、@、!で始まらないすべてのマッチから文字列を構成してください。 &[ – Yaniro

答えて

2

正規表現が一致するテキストを空の文字列に置き換えます。残っているのは、正規表現にマッチしなかったものです。

+0

私はこれを使用しています: '$ content = preg_replace( '/(#\ w * [a-zA-Z _] + \\ w *)|(!\\ w * [a-zA-Z_ ] + \ w *)|(\\ w * [a-zA-Z _] + \\ w *)|(\\ [[^ \\]] * \\])/ i '、' '、 $件名); ' 残りの空白をトリミングするだけです。 –

0

preg_match_allの代わりにpreg_splitを使用すると、1つの文字列を返すブレントの答えの代わりに、すべてのコンポーネントを間に入れます。多くの一致が空である可能性があることに注意してください。

+0

私は 'preg_match'を使って一致を反復し、文字列をコピーせずにデータを取り出すためにオフセットを保存する答えをタイプしましたが、このユースケースでは重すぎます。ローマには複数の方法があります。 –

0

私はこのコードをテストしていませんが、私はこの正規表現以外の考え方がうまくいくと思います。基本的には、文字列をスペースで分割し、各部分を解析します。このアプローチでは、部品の順序は関係ありません。

コンテンツとプロジェクトが複数の部分にまたがる可能性があるので少し難しいですが、私のコードでそれを処理する必要があります。また、1つのハットタグ、ユーザー、プロジェクト、およびツイートごとの優先度しか持たないことを前提としています。たとえば、複数のハッシュタグがある場合は、文字列ではなく配列に入れてください。最後に、奇妙なことが起きないようにするためのエラー処理はありません。

は、ここに私のテストされていないコードです:私はあなたが使用して、あなたの正規表現に誤りがあると思う

$data = array(
    'hash' => '', 
    'user' => '', 
    'priority' => '', 
    'project' => '', 
    'content' => '' 
); 

$parsingProjectName = false; 
foreach(explode(' ', $tweet) as $piece) 
{ 
    switch(substr($piece, 0, 1)) 
    { 
     case '#': 
      $data['hash'] = substr($piece, 1); 
      break; 
     case '@': 
      $data['user'] = substr($piece, 1); 
      break; 
     case '!': 
      $data['priority'] = substr($piece, 1); 
      break; 
     case '[': 
      // Check if the project name is longer than 1 word 
      if(strpos($piece, -1) == ']') 
      { 
       $data['project'] = substr($piece, 1, -1); 
      } 
      else 
      { 
       // There will be more to parse in the next piece(s) 
       $parsingProjectName = true; 
       $data['project'] = substr($piece, 1) . ' '; 
      } 
      break; 
     default: 
      if($parsingProjectName) 
      { 
       // Are we at the end yet? 
       if(strpos($piece, -1) == ']') 
       { 
        // Yes we are 
        $data['project'] .= substr($piece, 1, -1); 
        $parsingProjectName = false; 
       } 
       else 
       { 
        // Nope, there is more 
        $data['project'] .= substr($piece, 1) . ' '; 
       } 
      } 
      else 
      { 
       // We aren't in the middle of parsing the project name, and this piece doesn't start with one of the special chars, so assume it is content 
       $data['content'] .= $piece . ' '; 
      } 
    } 
} 

// There will be an extra space on the end; remove it 
$data['content'] = substr($data['content'], 0, -1); 
+0

ところで、私のsubstrの使用法を再確認する必要があるかもしれません。私はそれを使用して最初の文字、最後の文字を確認し、最初または最後の文字を除くすべてを取得します。私はそれが理にかなって、うまくいくことを願う –

0

\ wを使用すると、一致ワット\に対し、空白文字に一致するように望んでいたように見えます[-ZA-Z_]前単語文字。あなたは(この小さな部分のために)そのように行うことができます:あなたはすでにさまざまな部分を取得するために試合をループに思えたよう

...\\s*[\\w_]+\\s*... 

は、あなたがしたいプレーンテキスト用サブパターンを作成することもできますそれをパターンの残りの部分とマッチさせてください。この方法では、もう1つのマッチを追加するだけです。これは、マッチした部分をループしている間に、マッチした部分を区別する限り、内容の異なる順序でも機能します。

関連する問題