6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

preg_match()関数で正規表現を利用して文字列を分割する

Posted at

preg_match()の使い方を調べたのでメモ
正規表現をつかって文字列を分割して、
かつどんな文字列で分割したのかも知りたかった。

やりたかったこと

// これを
$array = [
    'foo_foo_1'   => 'f1',
    'bar_bar_1'   => 'b1',
    'hoge_hoge_1' => 'h1',
    'foo_foo_2'   => 'f2',
    'bar_bar_2'   => 'b2',
    'hoge_hoge_2' => 'h2',
    'foo_foo_3'   => 'f3',
    'bar_bar_3'   => 'b3',
    'hoge_hoge_3' => 'h3',
    // ...繰り返し
    'foo_foo_n'   => 'fn',
    'bar_bar_n'   => 'bn',
    'hoge_hoge_n' => 'hn',
];

// こんな感じにしたかった
$array = [
    1 => [
        'foo_foo' => 'f1',
        'bar_bar' => 'b1',
        'hoge_hoge' => 'h1'
    ],
    2 => [
        'foo_foo' => 'f2',
        'bar_bar' => 'b2',
        'hoge_hoge' => 'h2'
    ],
    3 => [
        'foo_foo' => 'f3',
        'bar_bar' => 'b3',
        'hoge_hoge' => 'h3'
    ],

    // ...繰り返し
    n => [
        'foo_foo' => 'fn',
        'bar_bar' => 'bn',
        'hoge_hoge' => 'hn'
    ],
];

つまり、foo_foo_nをfooとnに分割したい。(nは整数)

とりあえずやってみる

matches を指定した場合、検索結果が代入されます。 $matches[0] にはパターン全体にマッチしたテキストが代入され、 $matches[1] には 1 番目のキャプチャ用サブパターンにマッチした 文字列が代入され、といったようになります。

よくわからないけど
第3引数を指定すると検索結果が代入されるらしい。

$str = 'foo_foo_1';
preg_match('/_[\d]/u', $str, $matches);
var_dump($matches);

// array(1) { 
//   [0]=> string(2) "_1" 
// }

分割に使用した文字列は取得できた。
$matches[0]しか代入されてないけど。

分割された後の文字列も取得したい

$str = 'foo_foo_1';
$bar = preg_match('/(\w+)_[\d]/u', $str, $matches);
var_dump($matches);
// array(2) { 
//   [0]=> string(9) "foo_foo_1"
//   [1]=> string(7) "foo_foo"
// }

正規表現を()で囲むと$matches[0],$matches[1]に代入された。

$matches[0] // 元の文字列
$matches[1] // ()で囲んだ正規表現にマッチした文字列

"_1"が消えてしまった。
()で囲まないと正規表現全体にマッチした文字列が$matches[0]に代入されて、
()で囲むと上記のような結果が得られるみたい。

$str = 'foo_foo_1';
$bar = preg_match('/(\w+)_([\d])/u', $str, $matches);
var_dump($matches);
// array(3) {
//   [0]=> string(9) "foo_foo_1" 
//   [1]=> string(7) "foo_foo"
//   [2]=> string(1) "1" 
// }

欲しい結果を取得できた。

ただ$matches[1]や$matches[2]では使いづらい。

$matchesのキーに名前を指定できるようなのでやってみた。

$matchesのキーに名前を指定する

$str = 'foo_foo_1';
preg_match('/(?P<name>\w+)_(?P<num>[\d]+)/u', $str, $matches);
var_dump($matches);

// array(5) {
//   [0]=> string(9) "foo_foo_1"
//   ["name"]=> string(7) "foo_foo" 
//   [1]=> string(7) "foo_foo" 
//   ["num"]=> string(1) "1" 
//   [2]=> string(1) "1"
// }

やりたかった処理の実装

$array = [
    'foo_foo_1'   => 'foo1',
    'bar_bar_1'   => 'bar1',
    'hoge_hoge_1' => 'hoge1',
    'foo_foo_2'   => 'foo2',
    'bar_bar_2'   => 'bar2',
    'hoge_hoge_2' => 'hoge2',
    'foo_foo_3'   => 'foo3',
    'bar_bar_3'   => 'bar3',
    'hoge_hoge_3' => 'hoge3',

    'foo_foo_10'   => 'foo10',
    'bar_bar_10'   => 'bar10',
    'hoge_hoge_10' => 'hoge10',

    'foo_foo_101'   => 'foo101',
    'bar_bar_101'   => 'bar101',
    'hoge_hoge_101' => 'hoge101',
];

$result = [];

foreach ($array as $key => $value) {
    if(preg_match('/(?P<name>\w+)_(?P<num>[\d]+)/u', $key, $matches)) {
        $k = (int)$matches['num'];
        $result[$k][$matches['name']] = $value;
    }
}

var_dump($result);

/*
array(5) {
  [1]=>
  array(3) {
    ["foo_foo"]=>
    string(4) "foo1"
    ["bar_bar"]=>
    string(4) "bar1"
    ["hoge_hoge"]=>
    string(5) "hoge1"
  }
  [2]=>
  array(3) {
    ["foo_foo"]=>
    string(4) "foo2"
    ["bar_bar"]=>
    string(4) "bar2"
    ["hoge_hoge"]=>
    string(5) "hoge2"
  }
  [3]=>
  array(3) {
    ["foo_foo"]=>
    string(4) "foo3"
    ["bar_bar"]=>
    string(4) "bar3"
    ["hoge_hoge"]=>
    string(5) "hoge3"
  }
  [10]=>
  array(3) {
    ["foo_foo"]=>
    string(5) "foo10"
    ["bar_bar"]=>
    string(5) "bar10"
    ["hoge_hoge"]=>
    string(6) "hoge10"
  }
  [101]=>
  array(3) {
    ["foo_foo"]=>
    string(6) "foo101"
    ["bar_bar"]=>
    string(6) "bar101"
    ["hoge_hoge"]=>
    string(7) "hoge101"
  }
}
*/

これで良さげ

ちなみに正規表現の'\w'は注意がいるみたい

正規表現「\w」の説明の訂正(レシピ045)
http://php-recipe.com/?p=483

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?