2016-05-14 17 views
1

私はこのコードを持っている:preg_match_allの正規表現でサブパターンの結果を修正するにはどうすればよいですか?

$query = 'CREATE table "msg" ("myid" INT(10) UNSIGNED , "user" INT(10) UNSIGNED , "new_mes" SMALLINT(5) UNSIGNED , "total_mes" MEDIUMINT(8) UNSIGNED , "lastdate" DATETIME , PRIMARY KEY ("ids"), KEY ("lastdate"))'; 

私はこのsubpaternsを使用して主キーとキーを取得しようとしています:

preg_match_all('/(?:\WPRIMARY\W*KEY\W?\()(?P<PRIMARY_KEY>[^)]+)|'. 
     '(?:\W*KEY\W?\()(?P<KEY>[^)]+)/i',$query,$results); 
     $primary_key = isset($results['PRIMARY_KEY'][0]) ? $results['PRIMARY_KEY'][0] : ''; 
     $key = isset($results['KEY'][0]) ? $results['KEY'][0] : ''; 
    print_r($results); 

私はこの出力を得る:

Array 
(
    [0] => Array 
     (
      [0] => PRIMARY KEY ("ids" 
      [1] =>),KEY ("lastdate" 
     ) 

    [PRIMARY_KEY] => Array 
     (
      [0] => "ids" 
      [1] => 
     ) 

    [1] => Array 
     (
      [0] => "ids" 
      [1] => 
     ) 

    [KEY] => Array 
     (
      [0] => 
      [1] => "lastdate" 
     ) 

    [2] => Array 
     (
      [0] => 
      [1] => "lastdate" 
     ) 
) 

私が探しました二重引用符で囲まれた単語。結果はほぼ見いだされますが、私は最初のインデックス[0]で2つの単語 "ids"と "lastdate"を取得することをお勧めします。最初の単語が最初のインデックスに配置されているのに対して、2番目のインデックスが2番目のインデックスに配置されている理由を説明できますか?なぜ、2番目と1番目のインデックスに空の文字列があるのですか?

インデックス0の両方の単語を取得する方法はありますか?コードを単純化するだけです。

+0

名前付きキャプチャグループが必要ですか?あなたは単に ''(?| \ WPRIMARY \ W * KEY \ W?\((^))+)| \ W * KEY \ W?\(([^)] +)) '](https: //regex101.com/r/kG6nE6/1)。 [このデモ](http://ideone.com/sBLOYZ)を参照してください。 –

+0

私はそれらを必要としないことを知っています。私は物事を明確にするためにそれらを作成しました。 –

答えて

2

正規表現の動作を確認するには、右上のサイドバーのRegex101を使用します。

仕事(see online demo)を行うための別の方法:

<?php 
// I added a primary key `myid` to demonstrate a capture with several keywords 
$query = 'CREATE table "msg" ("myid" INT(10) UNSIGNED , "user" INT(10) UNSIGNED , "new_mes" SMALLINT(5) UNSIGNED , "total_mes" MEDIUMINT(8) UNSIGNED , "lastdate" DATETIME , PRIMARY KEY ("ids", "myid"), KEY ("lastdate"))'; 

// 1. Note the \b anchor to ensure that the capture begins at the start of a word 
// 2. PREG_SET_ORDER to keep structure simplier 
preg_match_all('#\b((?:PRIMARY\s*?)?KEY) \(([^\)]*)\)#i', $query, $results, PREG_SET_ORDER); 

$primary_keys = []; 
$keys = []; 

foreach ($results as $result) { 
    $values = explode(',', $result[2]); // get separate words 
    array_walk($values, function (&$v) { $v = trim($v, ' "'); }); // remove quotes and spaces 
    if (0 === stripos($result[1], 'PRIMARY')) { 
     $primary_keys = array_merge($primary_keys, $values); 
    } 
    else { 
     $keys = array_merge($keys, $values); 
    } 
} 

echo "Found primary keys:\n"; 
print_r($primary_keys); 
echo "Found keys:\n"; 
print_r($keys); 

echo "\n\$results:\n"; 
print_r($results); 

結果:あなたはthis new versionが、より効率的であることをRegex101で見ることができる

Found primary keys: 
Array 
(
    [0] => ids 
    [1] => myid 
) 
Found keys: 
Array 
(
    [0] => lastdate 
) 

$results: 
Array 
(
    [0] => Array 
     (
      [0] => PRIMARY KEY ("ids", "myid") 
      [1] => PRIMARY KEY 
      [2] => "ids", "myid" 
     ) 

    [1] => Array 
     (
      [0] => KEY ("lastdate") 
      [1] => KEY 
      [2] => "lastdate" 
     ) 

) 

その377のステップ対904とthe old one結果をキャプチャするステップ。

+0

ありがとうございます。これは良いです。あなたのパターンにはどのようなものがありますか? –

+1

@JohnBoeこれは、「PRIMARY」または「KEY」という単語の先頭を検索するために検索することを示します。正規表現エンジンは、解析するテキストの単語の先頭をテストするだけで、最適化することができます。 また、 'PRIMARY'や' KEY'を含む別の単語が 'FOREIGN KEY'のようにキャッチされないようにします。 – piouPiouM

関連する問題