2016-12-21 9 views
0

ブロックに配列にデータを渡す必要がありますが、どうすればいいですか?正規表現を使用する必要がありますか?私のスクリプトは、私が望むようにそれを分けることができないので、私にエラーを与えます。誰にもアイデアはありますか?文字列を多次元配列(正規表現)に構文解析する方法

データ:

~0 
11111111 
~1 
222222222 
~2 
3333333333 

     ~end 
~0 
aaaaaaaaaaa 
~1 
bbbbbbbbbb 
~2 
cccccccccc 
~3 
ddddddddddd 

     ~end 



~0 
yyyyyyyyyyy 
xxxxxxxx 
ffffffffff 
~1 
rrrrrrrrrrrr 
     ~end 

私はこのようにそれを必要とする:

Array ( 
    [0] => Array 
       (
        [0] => 11111111 

        [1] => 222222222 

        [2] => 3333333333 


       ) 

     ), 

    [1] => Array 
       (
        [0] => aaaaaaaaaaa 

        [1] => bbbbbbbbbb 

        [2] => cccccccccc 

        [3] => ddddddddddd 
       ) 

     ), 

    [2] => Array 
        (
         [0] => yyyyyyyyyyy 
xxxxxxxx 
ffffffffff 

         [1] => rrrrrrrrrrrr 

       ) 

     ), 



) 

私のコード(失敗):ここで

$texto = "~0 
11111111 
~1 
222222222 
~2 
3333333333 

     ~end 
~0 
aaaaaaaaaaa 
~1 
bbbbbbbbbb 
~2 
cccccccccc 
~3 
ddddddddddd 

     ~end 



~0 
yyyyyyyyyyy 
xxxxxxxx 
ffffffffff 
~1 
rrrrrrrrrrrr 
     ~end"; 

preg_match_all("/(?ms)^~0.*?~end/", $texto, $coincidencias); 

foreach ($coincidencias[0] as $bloque){ 
    preg_match_all("/\~.*\n/", $bloque, $sub_bloques); 
    $hola[] = $sub_bloques; 
} 
+0

私は私が正しく要件を理解全く確信していないが、あなたは確認してくださいだろうか? "caracter〜で始まらない空でない行は配列内の1つのエントリでなければなりません" – Dragos

+0

"〜0"から "〜終わり"までの@Dragosは1つのブロック(今は3つのブロック)であり、 〜0、〜1、〜2〜配列の位置(テキストのみ) –

+0

私はむしろ2つのステップで作業したいと思っています: 1. '$ level1 = explode( '〜end'、$ data)' 2. 'foreach($ @yyyyyyyyyyy (0サブタイトルとしてレベル1){$ matches = preg_match_all( '^(\ w *)$'、$ subItem)} ' – Dragos

答えて

3

は一つの非正規表現の方法です:文字列を分割行に挿入して反復処理します。指定した条件が満たされているかどうかを確認し、各行をサブアレイに追加します。その後、~end行に移動したら、サブ配列をメイン配列に追加します。正規表現解決のために

$sub_bloques = []; 
$hola = []; 

foreach(array_map('trim', explode("\n", $texto)) as $line) { 
    if ($line && substr($line, 0, 1) !== '~') { 
     $sub_bloques[] = $line; 
    } 
    if ($line == '~end') { 
     $hola[] = $sub_bloques; 
     $sub_bloques = []; 
    } 
} 

、あなたの条件を満たしている行を検索するセクションにpreg_match_all、その後、セクションにメインのテキストを分割する~endに爆発することから始めます。

foreach (explode('~end', $texto, -1) as $section) { 
    preg_match_all('/\n *(?!~)(\w+)/', $section, $matches); 
    if ($matches[1]) $result[] = $matches[1]; 
} 

(?!~)~で始まる行を除外するための負の後読みです。たぶん、クールな正規表現を使ってすべてを行う方法がありますが、それほどうまくいきません。

+0

xxxxxxxx ffffffffff )ist 1つのテキスト、新しい行ではなく、テキストには\ n ....があります。 –

+0

申し訳ありませんが、私はあなたが意味するものを理解しているか分かりません。それを私にもう少し説明しようと思いますか? –

+0

最後のブロック 〜0 yyyyyyyyyyy XXXXXXXX ffffffffff 、1つの文字ではなく、3つの位置がイスト –

0

出力配列にサブブロックをブロックに分割したいので、メソッドに2つのステップが必要です。その理由は、あなたのサブブロックが異なるキャプチャグループ数を持っており、正規表現はこの可変性を許さないからです。

コード:

// This delivers the sub-blocks in their relative blocks as requested in the OP 
foreach (preg_split('/\s+~end\s*/',$texto) as $bloque) { 
    if(preg_match_all('/(?:\~\d+\s+)\K.+?(?:\s+\S+)*?(?=\s+\~|$)/',$bloque,$sub_bloques)){ 
     $hola[]=$sub_bloques[0]; 
    } 
} 
var_export($hola); 

出力*再フォーマット/このページ(View Demo)上のスペースを節約するために凝縮:あなたが記載されているすべてのサブブロックを持つようにしたい場合は、

array(
    array('11111111','222222222','3333333333'), 
    array('aaaaaaaaaaa','bbbbbbbbbb','cccccccccc','ddddddddddd'), 
    array('yyyyyyyyyyy 
xxxxxxxx 
ffffffffff','rrrrrrrrrrrr') 
) 

また(ブロックで分割されていない)1次元配列では、出力配列は1ステップで構築できます。

if(preg_match_all("/(?:\~\d+\s*)\K.+?(?:\s+\S+)*?(?=\s+\~)/s", $texto, $coincidencias)){ 
    var_export($coincidencias[0]); 
} 

1次元の出力:

array (
    0 => '11111111', 
    1 => '222222222', 
    2 => '3333333333', 
    3 => 'aaaaaaaaaaa', 
    4 => 'bbbbbbbbbb', 
    5 => 'cccccccccc', 
    6 => 'ddddddddddd', 
    7 => 'yyyyyyyyyyy 
xxxxxxxx 
ffffffffff', 
    8 => 'rrrrrrrrrrrr', 
) 
+0

@VictorMoscosoLembcke私の答えが満足すれば、それに緑のダニを授与してください(潜在的に助けになるためにアップしてください)。何かが正しくない場合は、私にコメントを説明してください。私はそれを修正しようとします。 – mickmackusa

関連する問題