質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

5652閲覧

文字列を文字で分割し配列化する処理で、引用符で囲まれていない文字で分割する方法は?

sounisi5011

総合スコア697

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2015/01/19 13:27

CSSセレクタの分割用コードを書いており、文字列を,で区切る処理を書いています。
通常、ある文字で文字列を分割する場合、explodeを使った以下の方法となります。

lang

1$selectors = explode(',', $selector);

しかしこの方法を採用した場合、,で無差別に分割されるため、E[data-comma="a,b"]などのセレクタに対応出来なくなります。

Array
(
[0] => E[data-comma="a
[1] => b"]
)

求める処理は、引用符で囲まれていない文字,で文字列を分割する方法についてです。
そのような方法はあるのでしょうか?


処理コードの参考までに、引用符に囲まれた文字列にマッチする正規表現を置いていきます。
(引用符内でのエスケープ対応)

パターンにミスがあったため、以前のものから修正しています
"(?:[^"\]|\["\])+"|'(?:[^'\]|\['\])+'

lang

1preg_match_all('/"((?:[^"\\]|\\["\\])++)"|\'((?:[^\'\\]|\\[\'\\])++)\'/',$selector,$matches); 2 3// ダブルクォーテーションで囲まれた文字列の配列 4$q_strs =isset($matches[1]) ? $matches[1] : array(); 5// シングルクォーテーションで囲まれた文字列の配列 6$ap_strs=isset($matches[2]) ? $matches[2] : array();

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ngyuki様の追記です。
ダブルコーテーションで括られ、何もない状態の場合(”あ”,"",”abc”)、
2つ目のコーテーションが文字の分割場所として認識してくれないので
分割時に、「あ」「",”abc」と分割されてしまいます。
上記のような文字列が来る想定であれば下記の実装でも良いかと思います。

$pattern = <<<'EOS' (?:^|,) ( (?: "(?:[^"]|(?:\\)*\"|)+"| '(?:[^']|(?:\\)*\'|)+'| [^,] )* ) EOS; $pattern = preg_replace('/\s/', '', $pattern); preg_match_all("/$pattern/", $record, $matches);

投稿2018/08/15 01:36

編集2018/08/15 01:39
saramandark

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

しっかりと確認していませんが(また、CSS セレクタの具体的な定義もわかりませんが)、下記のようなかんじでしょうか。

lang

1$p = <<<'EOS' 2 (?:^|,) 3 ( 4 (?: 5 "(?:[^"]|(?:\\)*\")+"| 6 '(?:[^']|(?:\\)*\')+'| 7 [^,] 8 )* 9 ) 10EOS; 11 12$p = preg_replace('/\s/', '', $p); 13 14$s = 'aaa,E[data-comma="a,b"],bbb'; 15preg_match_all("/$p/", $s, $m); 16var_dump($m[1]);

(?:^|,)([^,]*)preg_match_all で文字列の分割をする定番のパターンで、([^,]*) の部分に例外条件となるパターンを追記します。


コメント投稿にあるように /x を使ってみました。

lang

1<?php 2$p = <<<'EOS' 3 # 先頭または区切り文字であるカンマ 4 (?:^|,) 5 6 # セレクタをキャプチャ 7 ( 8 # セレクタを構成する文字の繰り返し 9 (?: 10 # 二重引用符でクオートされたパターン 11 "(?:[^"]|(?:\\)*\")+"| 12 13 # 引用符でクオートされたパターン 14 '(?:[^']|(?:\\)*\')+'| 15 16 # カンマ以外の文字 17 [^,] 18 )* 19 ) 20EOS; 21 22$s = 'aaa,E[data-comma="a,b"],bbb'; 23preg_match_all("/$p/x", $s, $m); 24var_dump($m[1]);

投稿2015/01/20 01:36

ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sounisi5011

2015/01/20 03:37

期待通りの動作です! ありがとうございます。 --- PHPの正規表現では、パターン修飾子として`x`を指定するとパターン内の空白を無視します。 それでテストしてみたところ、動作します。 回答のコードは以下のように書きなおすことが可能です。 $p = <<<'EOS' / (?:^|,) ( (?: "(?:[^"]|(?:\\)*\")+"| '(?:[^']|(?:\\)*\')+'| [^,] )* ) /x EOS; $s = 'aaa,E[data-comma="a,b"],bbb'; preg_match_all($p, $s, $m); var_dump($m[1]);
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問