2016-07-03 12 views
1

私はphpとregexの新人です。問題に直面しています。php正規表現グループ

私はテキストは、たとえば次のようになります: "FIRST NAME:より多くのデータsdfksdfkjskdlfjlskdf:EXTRA DATA dsfkskldfjsdkfjsdkf:dsfksdfjlsdjfklsdf"

と私はより多くのデータおよびAのための3つのグループ、FIRST NAMEため互いにfecthしたいですEXTRA DATAの3番目です。

FIRST NAME:(.*)MORE DATA:(.*)EXTRA DATA:(.*)

これは私がJavaでそれを行う方法である:これは私の正規表現です。

が、今、私はPHPでそれと一致しないどのように私はエコーすることができますので、何かのように:例えば

echo "more data: " . matche(group(1));

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

EDIT:それを自分で繰り返すとどうなりますか?例えば:FIRST NAME: sdfksdfkjskdlfjlskdf MORE DATA: dsfkskldfjsdkfjsdkf EXTRA DATA: dsfksdfjlsdjfklsdf FIRST NAME: sdfksdfkjskdlfjlskdf MORE DATA: dsfkskldfjsdkfjsdkf EXTRA DATA: dsfksdfjlsdjfklsdfグループのループを終了して一致するまでグループ化するには?ご入力の上、厳密基づき

+0

は構造が常にランダムである参照してください。各セグメントの ':'の後の文字?もしそうなら、 'explode'を使い、その区切り文字で分割して配列を返すことができます。これ以上の制御が必要な場合は、 'preg_split'を使用することができます – djthoms

+1

** [this](http://ideone.com/xJOd46)** – rock321987

+0

@ rock321987ありがとう! –

答えて

1

:次に

$re = "/(FIRST NAME\\s*:)\\s*(.*)(MORE DATA\\s*:\\s*)(.*)(EXTRA DATA\\s*:\\s*)(.*)/"; 
$str = "FIRST NAME: sdfksdfkjskdlfjlskdf MORE DATA: dsfkskldfjsdkfjsdkf EXTRA DATA: dsfksdfjlsdjfklsdf"; 

preg_match_all($re, $str, $matches); 

$matches変数を確認してください。こうすると、一致するグループが表示されます(FIRST NAME:first-name-valueMORE DATA: more-data-valueEXTRA DATA: extra-data-value)。

+0

と私はそれを自己繰り返すことができますか? 'FIRST NAME:sdfksdfkjskdlfjlskdf詳細データ:dsfkskldfjsdkfjsdkf追加データ:dsfksdfjlsdjfklsdf FIRST NAME:sdfksdfkjskdlfjlskdf詳細データ:dsfkskldfjsdkfjsdkf追加データ:dsfksdfjlsdjfklsdf'どのようにして、ループが終了するまでグループをgrapしますか? –

+0

@ダンジンジジ(グループ内のすべてをキャプチャ)は、中括弧内のパターンを単純に囲みます。https://regex101.com/r/uK8hU5/1 –

1

さんはこのようにそれをやってみましょう:

preg_match('/FIRST NAME:\s*(.*?)\s*MORE DATA:\s*(.*?)\s*EXTRA DATA:\s*(.*)\s*/', $line, $matches); 

あなたの試合結果は次のように、$matchesになります。

php > var_dump($matches); 
array(4) { 
    [0]=> 
    string(93) "FIRST NAME: sdfksdfkjskdlfjlskdf MORE DATA: dsfkskldfjsdkfjsdkf EXTRA DATA: dsfksdfjlsdjfklsd" 
    [1]=> 
    string(20) "sdfksdfkjskdlfjlskdf" 
    [2]=> 
    string(19) "dsfkskldfjsdkfjsdkf" 
    [3]=> 
    string(17) "dsfksdfjlsdjfklsd" 
} 
php > 

だから今$matches[1]はように最初のグループである、と。 [0]は完全一致結果です。

0

あなたのregexは、最後の.*が0回以上の任意の文字と一致するため、任意の正規表現エンジンで改​​行なしの文字列ごとに1つの一致を見つけるように設計されています。

FIRST NAME:(.*?)MORE DATA:(.*?)EXTRA DATA:(.*?)(?=$|FIRST NAME:) 
      ^^^^^   ^^^^^   ^^^^^ ^^^^^^^^^^^^^^^^ 
:あなたの入力は常に持っている場合、これらの3つの部分は何回でも繰り返す

は、我々は、文字列の末尾またはFIRST NAME:まで一致させることを確認するために怠惰なドットマッチングを使用して、最後の1の後に肯定先読みを追加します

ここthis regex demo

を参照してください、(.*?)試合0+できるだけ数倍の改行以外の任意の文字、および(?=$|FIRST NAME:)ゼロ幅アサーションは最初に来るものまで一致.*?が必要です:文字列の末尾またはFIRST NAME:のいずれか。

PHPノート:Javaでは、部分一致を見つけてwhileループを実行するには、Matcher#findを使用します。PHPでは、あなただけ​​:

$re = "/FIRST NAME:(.*?)MORE DATA:(.*?)EXTRA DATA:(.*?)(?=$|FIRST NAME:)/"; 
$str = "FIRST NAME: sdfksdfkjskdlfjlskdf MORE DATA: dsfkskldfjsdkfjsdkf EXTRA DATA: dsfksdfjlsdjfklsdf FIRST NAME: sdfksdfkjskdlfjlskdf MORE DATA: dsfkskldfjsdkfjsdkf EXTRA DATA: dsfksdfjlsdjfklsdf"; 
preg_match_all($re, $str, $matches); 
print_r($matches[1]); // Print Group 1 
print_r($matches[2]); // Print Group 2 
print_r($matches[3]); // Print Group 3 

そして、あなたは正規表現の最適化ファンなら、怠惰なマッチンググループをアンロール:

FIRST NAME:([^M]*(?:M(?!ORE DATA:)[^M]*)*)MORE DATA:([^E]*(?:E(?!XTRA DATA:)[^E]*)*)EXTRA DATA:([^F]*(?:F(?!IRST NAME:)[^F]*)*) 

は、英数字、regex demo