正規表現で文字列間に文字列を挿入 - PHPプロ!Q&A掲示板

2268

  • 0P

正規表現で文字列間に文字列を挿入

質問日時 / 2009年9月14日 16:07    回答数 / 2件

Questioner:  livei  このエントリーをはてなブックマークに追加 

キーワード / 正規表現    置換    perl   

Perl互換のpreg_replace関数を使った置換を行おうとしているのですが、やりたいことがうまく実現できません。

やりたいことは、

・<tagA>という文字列と</tagA>のあいだに<tagInsert>という文字列を挿入したい
・ただし、<tagA>の中に<tagB>という文字列がある場合は、その<tagB>の下に挿入したい


<失敗した正規表現> 
  1. $new_str = preg_replace("/<tagA(.*?)>(.*?)(<(?!tagB).)*/", '<tagA\\1>\\2<tagInsert>\\3', $str);

<実現したい例>
  1. <tagA>
  2.   <tagB> 
  3.   <tagB> 
  4.   <tagC> 
  5. </tagA>

↓置換実行 
  1. <tagA> 
  2.   <tagB> 
  3.   <tagB> 
  4.   <tagInsert> 
  5.   <tagC> 
  6. </tagA>

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┣A01kaitau >>CODE /<tagA(.*?)>(.*?)(<(?!tagB).)*/ <<CODE
┃┗A01-1liveiご返信遅くなって申し訳ありません。 ご指摘ありが
┗A02magicflute2この意見は投稿者によって削除されました。

回答一覧

並び替え:

A01 満足
answererkaitau [9月14日 18:40]


  1. /<tagA(.*?)>(.*?)(<(?!tagB).)*/

まず、このパターンだと、最初の行しか検索しないので、s修飾子をつけてあげる必要があります。
http://jp.php.net/manual/ja/reference.pcre.pattern.modifiers.php

他に問題なのが、
(<(?!tagB).)*
になります。
「< の後に tagBで続かない一文字」・・・なのですが、0回以上のマッチなので、
無くてもいいことになってしまってます。

<tagA> の後に必ず < (</tagA>も含めて)が来る前提であれば、
(<(?!tagB).*)
であれば、
「「< の後にtagBで続かない0文字以上の文字」のパターン」
となるので、後方参照の二番目は<tagB以前の方に行って、
<tagB以降が三番目に入るようになると思います。

まとめると

  1. /<tagA(.*?)>(.*?)(<(?!tagB).*)/s
みたいな形でしょうか。

preg_replaceで試行錯誤する前に
  1. <?php
  2. preg_match(<パターン>,$str,$matches);
  3. var_dump($matches);
でいろいろ試すと、何がどこまでマッチしているか把握しやすいかもしれません。

この意見に回答する

ツリーへ TOPへ

A01-1
replyerlivei [9月19日 16:27]

ご返信遅くなって申し訳ありません。

ご指摘ありがとうございました!
希望通りの動作をしました。
教えていただいた正規表現をまだしっかり理解できていないので、これからゆっくり見てどういうことなのか理解していこうと思います。^^

この意見に回答する

ツリーへ TOPへ

A02
answerermagicflute2 [9月15日 12:49]

この意見は投稿者によって削除されました。

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
負荷時のmysql_connect()エラー
 このエントリーをはてなブックマークに追加 
A
これはPHPというよりOSまたはMySQLのコミュニティで質問されたほうがいいと思います。 ぱっと思いついた範囲で記すと MySQL等のDBに「ある時点において同時に接続可能なクライアントの最大数」に制限があるよう...

>>続きを読む

今回のような実践的な経験がエンジニアのキャリアに繋がると思います。是非サービスを成功させて下さい!

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)