2016/03/15 12:17:28

PHPの正規表現(preg_match_all)で抽出した要素に任意のキーをつける


Warning: Attempt to read property "post_excerpt" on null in /home/kpkyvkzp/public_html/unskilled.site/wp-content/themes/unskilled2/content-header-eyecatch.php on line 5
目次(クリックするとジャンプします)
  • 1:キー付けよう
  • 2:連想配列を得るテスト
  • 3:まとめ

キー付けよう

preg_match_allで要素抽出を行うと得られる配列は添字配列(キーが数字のやつ)になります。

これはこれで便利なときもあるのですが、連想配列になってくれたら便利な時も結構あるんですよね。

そこで正規表現の書き方で要素に任意のキーが付けられる方法です。わ〜い。

部分要素を抽出するためにカッコで囲むことを「サブパターン」と呼びますが、キーをつけることを「名前つきサブパターン」とか呼ぶそうですよ。

2種類の書き方ができます。

(?<name>pattern)

(?'name'pattern)

これを踏まえてパターンを書くと以下のような感じになります。

/(?<URL>https://[a-z.]*(?<TDL>.[a-z]{2,3})/?)/
/(?'URL'https://[a-z.]*(?'TDL'.[a-z]{2,3})/?)/

連想配列を得るテスト

以下の例文でテストしてみます。

googleのページはhttps://www.google.co.jp/で、wikipediaはhttps://ja.wikipedia.org/です。またyoutubeはhttps://www.youtube.comです。URL全体とトップレベルドメインの両方を得たいとします。 

URL全体とトップレベルドメインを抽出しそれぞれURLTLDというキーを付けたいと思います。

  • [“URL”]
  • [“TLD”]

以下のようなスクリプトを書いてみました。

上記のスクリプトでは全体をカッコで囲んでいますが、こうしないとURLとして抽出した要素にキーを付けられません。添字[0]に正規表現全体のマッチ結果が出力されるので、冗長になってしまいますが、仕方がないのかな。

出力は以下の様になりました。ちゃんと["URL"]["TDL"]で出力されていますね。

array(3) {
  [0]=>
  array(5) {
    [0]=>
    string(25) "https://www.google.co.jp/"
    ["URL"]=>                                                                                                                                   [0/125]
    string(25) "https://www.google.co.jp/"
    [1]=>
    string(25) "https://www.google.co.jp/"
    ["TDL"]=>
    string(3) ".jp"
    [2]=>
    string(3) ".jp"
  }
  [1]=>
  array(5) {
    [0]=>
    string(25) "https://ja.wikipedia.org/"
    ["URL"]=>
    string(25) "https://ja.wikipedia.org/"
    [1]=>
    string(25) "https://ja.wikipedia.org/"
    ["TDL"]=>
    string(4) ".org"
    [2]=>
    string(4) ".org"
  }
  [2]=>
  array(5) {
    [0]=>
    string(23) "https://www.youtube.com"
    ["URL"]=>
    string(23) "https://www.youtube.com"
    [1]=>
    string(23) "https://www.youtube.com"
    ["TDL"]=>
    string(4) ".com"
    [2]=>
    string(4) ".com"
  }
}

添字配列としても出力されていますが、キーで処理する際に特に邪魔にならないので、この形でも問題無いです。むしろ添字配列としても、連想配列としても扱えるので便利かもしれません。こういうのもデータ構造っていうのだろか?

ちょっとforeachで回してみます。

キーで要素を指定できるようになっていますよね。添字ではやりにくい処理もこれでできるようになりますよ。コードも読みやすくなるかも。

string(25) "https://www.google.co.jp/"
string(3) ".jp"
string(25) "https://ja.wikipedia.org/"
string(4) ".org"
string(23) "https://www.youtube.com"
string(4) ".com"

まとめ

名前つきサブパターン」で要素にキーが付けることができる。正規表現の結果を連想配列で得ることができるようになる。

書き方

(?<name>pattern)

(?'name'pattern)

/(?<URL>https://[a-z.]*(?<TDL>.[a-z]{2,3})/?)/
/(?'URL'https://[a-z.]*(?'TDL'.[a-z]{2,3})/?)/