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

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

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

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

3回答

5502閲覧

正規表現でネストした括弧()の最短マッチする方法

helloman

総合スコア39

PHP

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

1クリップ

投稿2020/01/27 04:41

編集2020/01/27 04:51

正規表現でネストした括弧()の最短マッチする方法考え中です。
/([\s\S]+)/ とか /([\s\S]+?)/
だとネストされているとうまくいかず、、、
構造をに合わせたマッチする方法があればと思い質問させていただきました。

ああああああああ ( いいいいいいいい ( うううううううう ( ええええええええ ) ) ) おおおおおおおお かかかかかかかか ( きききききききき ( くくくくくくくく ) ) けけけけけけけけ ここここここここ

↓↓↓この部分を取得したい

( いいいいいいいい ( うううううううう ( ええええええええ ) ) ) ( きききききききき ( くくくくくくくく ) )

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

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

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

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

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

KojiDoi

2020/01/27 04:44

言語は何ですか?
helloman

2020/01/27 04:51

PHPです。入力するの忘れてました。 修正しました。
m.ts10806

2020/01/27 06:02

「最短マッチ」とはなにでしょうか
guest

回答3

0

ベストアンサー

こんにちは

XMLに変換してからパースするという方法はいかがでしょうか?

php

1$text = <<<TEXT 2ああああああああ 3( 4 いいいいいいいい 5 ( 6 7 うううううううう 8 ( 9 ええええええええ 10 ) 11 ) 12) 13 14おおおおおおおお 15 16かかかかかかかか 17( 18 きききききききき 19 ( 20 くくくくくくくく 21 ) 22) 23けけけけけけけけ 24ここここここここ 25TEXT; 26 27 28$text = str_replace('(', '<node>', $text); 29$text = str_replace(')', '</node>', $text); 30 31$xmlstr = 32 '<?xml version="1.0" encoding="UTF-8"?>' . 33 '<root>' . 34 $text . 35 '</root>'; 36 37 38$doc = new SimpleXMLElement($xmlstr); 39 40$count = 0; 41foreach ($doc->xpath('/root/node') as $node) { 42 $count ++; 43 $str = $node->asXML(); 44 $str = str_replace('<node>', '(', $str); 45 $str = str_replace('</node>', ')', $str); 46 echo $count . "個目 ==========\n"; 47 echo $str . "\n"; 48}

上記を実行すると、以下のような出力が得られます。

1個目 ========== ( いいいいいいいい ( うううううううう ( ええええええええ ) ) ) 2個目 ========== ( きききききききき ( くくくくくくくく ) )

補足

以下、参考までに補足します。

使用するプログラミング言語は異なりますが、二週間ほど前に、類似の質問がありました。

上記の質問に対する、私の回答 では所与の文字列からJSONを経由しましたが、このご質問では、XMLにして処理するのが手っ取り早いと思ったのでそのようにしました。ちなみに、そちらの回答の補足やコメントにも書きましたが、開くカッコと閉じるカッコがきちんと対応している文字列にマッチする正規表現を書けないことを、理屈として理解するためには、(上記回答のコメントでも書きましたが)、一度、以下のような本で学習されるとよいかと思います。

以上、参考になれば幸いです。

投稿2020/01/27 06:52

jun68ykt

総合スコア9058

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

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

helloman

2020/01/27 09:10

アイデアに感動です。 「pythonで入れ子上になったテキストの階層構造を取り出す」 も勉強になります。 ご回答ありがとうございました。
jun68ykt

2020/01/27 10:00

どういたしまして。 > 「pythonで入れ子上になったテキストの階層構造を取り出す」 > も勉強になります。 とのことで、よかったです????
guest

0

最短マッチさせずに最初と最後のカッコをとって
その中にあるカッコをひろうとか・・・

投稿2020/01/27 05:13

yambejp

総合スコア117646

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

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

yambejp

2020/01/27 05:14

並列だったり3重4重となってりいろいろ考えられるので難しいのは確か PHPのマッチング処理はオフセットをとれるので検索開始位置を 調整することは可能だと思います
helloman

2020/01/27 05:25

ちょっと挑戦してみます。
helloman

2020/01/27 05:49

難しすぎて私にはできそうにありませんでした。
yambejp

2020/01/27 06:47 編集

・カッコの組み合わせはかならず()が1対1で存在する ・3重目のカッコは並列データがない などの条件がそろえばやりようはあります 以下、とりあえず冗長に処理をかいてみました $matchを2や3にあげて確認してみてください
yambejp

2020/01/27 06:46

$str=<<<eof ああああああああ ( いいいいいいいい ( うううううううう ( ええええええええ ) ) ) おおおおおおおお かかかかかかかか ( きききききききき ( くくくくくくくく ) ) けけけけけけけけ ここここここここ eof; preg_match_all("/(|)/",$str,$m,PREG_OFFSET_CAPTURE); $match=1; //ここでレベルを指定する $level=0; $m=array_map(function($x) use(&$level){ $ret=[$x[1]]; if($x[0]=="("){ $level++; $ret[]=$level; } if($x[0]==")"){ $ret[]=$level; $level--; } return $ret; },$m[0]); $data=[]; $flg=true; foreach($m as $val){ if($val[1]==$match){ if($flg){ $data[]=[$val[0]]; }else{ $data[count($data)-1][]=$val[0]; } $flg=!$flg; } }; foreach($data as $val){ print substr($str,$val[0],$val[1]-$val[0]+1)."<br>"; }
helloman

2020/01/27 09:07

ありがとうございます。 感動です。勉強になります。
guest

0

「段数がわからない、左右のバランスが取れたカッコ」とマッチさせるのは、本来の正規表現では行えない操作です。

PHPのPCREなど(参考)、拡張により可能となっている処理系もありますが、記法がややこしい、マッチしないパターンの場合処理時間を浪費してしまう危険があるなど、正規表現で行うのが適切ではないタスクです。

括弧の数を数えつつ文字列を1文字ずつ読んでいくなど、他の方策を考えたほうがいいでしょう。

投稿2020/01/27 04:58

maisumakun

総合スコア146543

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

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

helloman

2020/01/27 05:06

違うやり方を考えてみます。 ちなみに「括弧の数を数えつつ文字列を1文字ずつ読んでいくなど」 はそのようにしたらいいでしょうか?
m.ts10806

2020/01/27 06:02

一文字ずつ切り出してくのが良さそうですね。
helloman

2020/01/27 09:08

ご回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問