2011-06-30 16 views
3

は(正確に)これ、preg_match_all()で検索ポインタを移動/リセットする方法はありますか?

preg_match_all("/(^|-)[a-z]+(-|$)/i", "foo-bar-moo", $matches); 

を、次の例を見てください、次のマッチを返す

foo- 
-moo 

しかし、私は以下を生成する必要がある、出力に一致する

foo- 
-bar- 
-moo 

があります実際にこれを行う方法?たとえば、一致した後に検索ポインタを1文字戻してみましょう。

唯一のアイデアは、while()のループにこれを入れ、すべての一致が見つかるまで各ループの一致を削除することです。

ありがとうございました。

編集:問題をより明確にするために問題を簡略化しようとしましたが、そうすることで実際の問題点を誤って伝えているようです。謝罪。

基本的には、直前の文字または直後の文字が特定の文字だったが、同時にこれらの先頭と末尾の文字を一致させずに文字列内の単語に一致させる方法が必要でした。

私はあなたがこれを行うことができなかった印象を受けていたので、代わりに先行/後ろの文字をキャプチャして自分で削除することに決めました。これは上記の問題に私を導いた。

Tim Pietzckerが指摘したように、私が実際に必要としたのはlookaroundsでした。

は、したがって、上記の私の例のために、解決策は以下のように、ある

preg_match_all('/(?<=^|-)[a-z]+(?=-|$)/', "foo-bar-moo", $result); 

そして、それは答え、助けをもう一度、

foo 
bar 
moo 

感謝を出力します。

preg_match_all("/(^|-)([a-z])+(-|$)/i", "foo-bar-moo", $matches); 

についてあなたは[FOO、バー、MOO]を得るでしょう何

+0

ハイフンをオプションにすることはできますか(これは構文だと思いますか)。 (^ | - )?[a-z] +( - | $)? –

+0

いいえ、一致する場合は '-'を取り上げる必要があります。 –

答えて

1

ルックアラウンドを使用して、ルックアラウンド式にキャプチャグループを配置します。これにより、1つのpreg_match_all()コールでそれを行うと、まだ- ESをキャプチャすることができます存在する場合:

preg_match_all('/(?<=(^|-))([a-z]+)(?=(-|$))/', $subject, $result, PREG_SET_ORDER); 
for ($match = 0; $match < count($result); $match++) { 
    echo $result[$match][1] . $result[$match][2] . $result[$match][3]; 
} 
+0

あなたは学者で紳士です。私の質問の例は、私の実際の問題(申し訳ありません)からかなり抽象的であり、見た目の表現は私の問題を解決するために必要なものです。ありがとうございました。 –

0

+0

+1グループを創造的に使用します。 – Nightfirecat

+0

私は何かが欠けていない限り、それは私の質問の正規表現とは何もしないし、同じ結果を与える? –

1

preg_matchoffsetパラメータを使用する必要があると思います。 0から始まり、最初に一致するのは-*[a-z]-*です。 matchOffset + matchLength - #dashesAtEndを取得し、それを次のpreg_matchコールへのオフセットとして使用します。

+0

これはオプションです。しかし、私はテスト中の大きなコンテンツと_long_生成された正規表現を持っています。理想的には、私は 'preg_match_all()'に何かを渡したいので、パフォーマンスのために一度だけ実行する必要があります。 –

+0

@Stephen、私はpreg_match_allが現在のオフセットを減らさないことを除いて、ほとんど同じことをしなければならないと思います。あなたはそれがパフォーマンス上の問題だと確信していますか? –

+0

@ agent-j:いくつかのベンチマークを行い、それを複数回実行することが実際に影響を与えるかどうかを確認します。しかし、提案のための乾杯。私はそれを使用できることを願っています。 –

0

あなたが必要な思想:

Array 
(
    [0] => foo- 
    [1] => -bar- 
    [2] => -moo 
) 

しかし、私はあなたの更新質問から見ることができるように、これはすべき

preg_match_all("/(?-)[a-z]+(?-)/i", "foo-bar-moo", $matches); 

echo $matches[0]; 

Array 
(
    [0] => foo 
    [1] => bar 
    [2] => moo 
)