SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 社員募集 ...

【正規表現】テキストから、項目 => 値 の組み合わせを取り出す

問題

以下のようなテキストから、項目 => 値 の組み合わせを、正規表現で取得せよ。

資料請求フォームからデータが送信されました。
---
[項目1 例えば名前]
  ソフテルさん
[項目2 例えば年齢]
  10歳
[項目3 例えば住所]
  岐阜県
[項目4 例えば職業]
  システム開発

解答例

phpのpreg_match_all()関数を使って取得すると、以下のような感じです。

//$strに問題のテキストが入っているとする
preg_match_all('/(?:\[(.*?)\](.*?)(?=(?:\[|$)))/s', $str, $matches);

$matches の中身を確認すると、以下の通り。

array(3) {
  [0]=>
  array(4) {
    [0]=>
    string(47) "[項目1 例えば名前]
  ソフテルさん
"
    [1]=>
    string(34) "[項目2 例えば年齢]
  10歳
"
    [2]=>
    string(38) "[項目3 例えば住所]
  岐阜県
"
    [3]=>
    string(46) "[項目4 例えば職業]
  システム開発"
  }
  [1]=>
  array(4) {
    [0]=>
    string(23) "項目1 例えば名前"
    [1]=>
    string(23) "項目2 例えば年齢"
    [2]=>
    string(23) "項目3 例えば住所"
    [3]=>
    string(23) "項目4 例えば職業"
  }
  [2]=>
  array(4) {
    [0]=>
    string(22) "
  ソフテルさん
"
    [1]=>
    string(9) "
  10歳
"
    [2]=>
    string(13) "
  岐阜県
"
    [3]=>
    string(21) "
  システム開発"
  }
}

ここまで取れれば、$matches[1] と $matches[2] を使って、あとは何とかなります。

値の方には改行などが混じっているので、trim()などして取り除きます。

$x = array();
foreach ($matches[1] as $k => $v) {
	$x[trim($v)] = trim($matches[2][$k]);
}
array(4) {
  ["項目1 例えば名前"]=>
  string(18) "ソフテルさん"
  ["項目2 例えば年齢"]=>
  string(5) "10歳"
  ["項目3 例えば住所"]=>
  string(9) "岐阜県"
  ["項目4 例えば職業"]=>
  string(18) "システム開発"
}

補足

/(?:\[(.*?)\](.*?)(?=(?:\[|$)))/s ってどういう意味?

パターン修飾子 s により、ドット(.)は改行にもマッチする。

*? で、短くマッチする(貪欲でなくする)。

この場合はどちらでもよいのだが、キャプチャしなくてよいパターンには ?: をつけると、グループ化はするけどキャプチャはしなくなる($matches に入ってこない)。

xxx(?=yyy) は肯定的前方先読み。続いてyyyが現れるxxxにマッチする。この場合だと次の [ か行末が続くところにマッチする。

項目と値はキャプチャしたいので括弧でくくって (.*) と書いた。

値の方に、この場合だと [ が入っていると、期待したようにマッチしないことがあるので注意。

関連するメモ

コメント