PHP5正規表現でマッチングできない問題についての解決方法

このQ&Aのポイント
  • PHP5の正規表現を使用して文字列中の独自タグをパースする際に問題が発生しています。
  • 期待した結果としては、<tag>タグの間の文字列を正しくマッチングさせることですが、実際には全てのタグが一つのマッチとして扱われます。
  • この問題を解決するために、正規表現パターンを修正する必要があります。具体的な方法としては、マッチしたタグの末尾に ? を追加することで、最短マッチングを行うことができます。
回答を見る
  • ベストアンサー

PHP5の正規表現でうまくマッチできない

PHP5の正規表現で文字列中の独自タグをパースしようとしていて、 うまくいかず困り果てています。 正規表現パターンは、/<tag>.*<\/tag>/ 対象文字列は、<tag>こんにちは</tag><tag>こんばんは</tag> preg_match_all('/<tag>.*<\/tag>/', '<tag>こんにちは</tag><tag>こんばんは</tag>', $result) でマッチした文字列は、 $result[0]:<tag>こんにちは</tag> $result[1]:<tag>こんばんは</tag> となることを期待しているのですが、 実際は、 $result[0]:<tag>こんにちは</tag><tag>こんばんは</tag> となりました。 <tag>タグの間に入る文字列長、文字列フォーマットは不定です。 どうすれば期待通りの振る舞いに出来るでしょうか?

  • PHP
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1
jontoo
質問者

お礼

所要の振る舞いにすることができました。 返信ありがとうございました。

その他の回答 (1)

noname#244856
noname#244856
回答No.2

最短マッチを使ってもいいですが、最速の正規表現を書くならば独占的最長マッチを用いて @<tag>[^<]*+</tag>@ とする方がオススメです。また、おそらく >> 実際は、 >> $result[0]:<tag>こんにちは</tag><tag>こんばんは</tag> >> となりました。 において $result[0] → $result[0][0] の誤りですよね。欲しいのはInnerHTMLだと思うので @<tag>([^<]*+)</tag>@ として、 $result[0][0] … OuterHTML $result[1][0] … InnerHTML にセットされるようにしてみましょう。なお、配列生成方式には - PREG_PATTERN_ORDER(デフォルト) - PREG_SET_ORDER の2種類がありますが、 「OuterHTMLもInnerHTMLも両方扱いたい」 という場合は PREG_SET_ORDER に変更したほうが使い勝手が向上するでしょう。この場合では $result[0][0] … OuterHTML $result[0][1] … InnerHTML となります。逆に 「InnerHTMLしか使わない」 という場合はデフォルトでいいと思います。

jontoo
質問者

お礼

最短マッチを使うことにしました。 今後独占的最長マッチ使う場合もありえる為詳しく調べてみます。 返信ありがとうございました。

関連するQ&A

  • PHPの正規表現「preg_match」で漢字を含む場合のマッチパター

    PHPの正規表現「preg_match」で漢字を含む場合のマッチパターンについて 宜しくお願い致します。 preg_matchを使っての正規表現で、「あいうえおかきくけこ3月10日さしすせそ」という文字列から「3月10日」だけを抽出するには、どういうパターンが良いのでしょうか? 下記の様にやってみましたが、だめでした。。。 preg_match("/\d{1,2}[月]\d{1,2}[日]/",$hoge,$match) これではうまくいきません。 どなたかお助けくださいー!

    • ベストアンサー
    • PHP
  • 正規表現のコーディングについてお願いします。

    こんにちは、よろしくお願いいたします。 正規表現パターンを書く場合に皆さんがどのようにされているか教えてください。 例えば(ちょっとムリヤリ感が強いですが)、'Price \5800-' という文字列の \5800 の部分に preg_match でマッチさせたいとします。 単純に考えると、 /\\\d+/ のようなパターンが思いつくのですが、それを文字列として preg_match に渡す際に、コードはどのように書かれますか? <?php   $str = 'Price \5800-';   //とりあえず、'/\\\d+/' と書き、'/\\\\\\d+/' と、\ をそれぞれの \ に書き足す   if ( preg_match('/\\\\\\d+/', $str, $match) ) {     print_r($match);   } ?> 「まず、パターンを書き、全ての \ の前に \ を書き足す。」というのが無難なのかな?と思い、そうしていますが、 そういった考え方で間違っていないでしょうか? どうぞよろしくお願いいたします。

    • 締切済み
    • PHP
  • PHP 正規表現改行したい

    preg_match でHTMLタグを解析するために正規表現を組んでますが、正規表現部分が長すぎてソースがわかりづらいので機能に影響すること無く改行して見やすくする方法はありますか? もしくはHTMLのパースならこうした方がいいよ的アドバイスでも

    • ベストアンサー
    • PHP
  • 正規表現

    いつもお世話になっております。 早速質問させていただきます。 文字列中に {{○}} を検索し、マッチさせるための 正規表現を教えてください。 (中括弧×2 英数字 中括弧×2) ○には、英数字が入る可能性がございます。 {{○}} は複数個あるかもしれないので、preg_match_all() を 使用したほうがいいかと考えております。 よろしくご教示お願いいたします。

    • ベストアンサー
    • PHP
  • PHPにおける正規表現について

    PHPにおける正規表現について ご教授ください。 いわゆる、対象の文字列が複数行にわたっていた場合のことです。 $data = <<< EOF ABCDE FGH EOF; $hoge = preg_match("/EF/" ,$data,$match); と上記のようなコードがあった場合 対象の文字列群から【EF】という文字列を検索したい場合、どのように記述したら 【E(間に改行)F】の文字列と一致させる事ができるでしょうか? 仮に正規表現の修飾子の【s】や【m】を用いても上記の例の場合 一致させることができないと思います。 やはり、対象の文字列群 $data の改行文字をいったん削除したものから検索 するのがベターでしょうか? 正規表現に造詣の深い方よろしくご教授ください。

    • ベストアンサー
    • PHP
  • preg_matchの正規表現がうまくいかない

    たとえば、http://gehasoku.com/?p=2のソースコードには ------------------- <rdf:Description rdf:about="http://www.com/aaa.html" trackback:ping="http://www.com" dc:title="タイトル" dc:identifier="http://iii.com/bbb.html" dc:subject="ハードウェア" dc:description="1 名前:名無しさん " dc:creator="soft_net" dc:date="2012-02-21T20:05:01+09:00" /> ------------------- のような形の<rdf:Description~~~/>タグの情報ががいくつかあると思います。これらすべてを文字列として取得したくて、次のようなphpを作成しましたが、うまく動作しません。 原因はどうやらpreg_match_allの正規表現がうまくいっていないからのようですので、 <rdf:Description~~~/>を抜き出すことができる正規表現を教えてください。 自分でもここでチェックしながらやりましたが、 http://www.rider-n.sakura.ne.jp/regexp/regexp.php <rdf:Description~をマッチすることはできても、/>で閉じることができませんでした。 よろしくお願いします。 <?php $url="http://gehasoku.com/?p=2"; $html=file_get_contents($urls); preg_match_all("/<rdf:Description(.*)?\/>/",$html,$match); print_r($match); foreach($match[1] as $value){ echo $value; } ?>

    • ベストアンサー
    • PHP
  • 全角カタカナの正規表現

    if (preg_match('/[ァ-ヶー]+/', $value, $match )) { print ("$value"."はカタカナです。"."($match[0])"."<br />") } else { print ("$value"."はカタカナではない。<br />"); } という感じで全角カタカナにマッチさせる正規表現を使いたいのですが、このやり方だと「全角カタカナを含んでいる…」という表現になってしまいます。ある文字列が「すべて全角カタカナである」という正規表現を考えているのですが、なかなかうまくいきません。逆引きのサンプルなんかでもなかなか見つからなくて困っています。  同様に「すべて平仮名にマッチ!」というのにも応用できると思うのですが、なかなかうまく行きません。  是非、そのやり方やヒントをおしえてください。  マルチバイト対応なので[ぁ-ん]のような形で表記できます。またPerl互換(preg_match)で作っているので、Perlに詳しい方も是非是非おしえてください。

    • ベストアンサー
    • PHP
  • 正規表現について

    お世話になります。 ●●● ●●● という文字列かどうか判断する正規表現を作成したいです。 条件としては、 ・「文字1 (←全角スペース)文字2」という感じで、文字1と文字2に全角スペースが挟まれている感じで、文字列の先頭にも末尾にも空白文字は入ってはいけない(真ん中に1つのみ) ・文字1と文字2には、数字・空白以外の文字が入る(主に感じ・ひらがな・カタカナが入る)(文字数は一文字以上) といったところです。 自分で作成した正規表現は、 $pattern = '/^([\d\S])+ ([\d\S])+$/'; if( !preg_match($pattern,$chkStr) ) print "マッチしていない"; } なんですが、どうもマッチしてほしい文字にマッチしていないようなのです。 お手数ですがご教授ください。

    • ベストアンサー
    • PHP
  • 正規表現にて質問があります。

    テスト勉強をやっていて過去問をみたら正規表現の部分だけわからずにいます (1)α=(0|10)*2(1|00|010)+ (2)α=(ab|c)*c(bc|a)+ (3)α=(1|22)*a(333|4444)* (1)正規表現αが表す文字列内、文字列長が1のものすべてを列挙せよ (2)正規表現αが表す文字列内、文字列長が2のものすべてを列挙せよ (3)正規表現αが表す文字列内、文字列長が3のものすべてを列挙せよ (4)正規表現αが表す文字列内、文字列長が4のものすべてを列挙せよ の答えを教えてもらえないでしょうか? もしよろしければどうやってとけばいいかのアドバイスもお願いします

  • 文字列全体に対する置き換え [正規表現]

    正規表現での文字列全体に対する、マッチ箇所 への置き換えについて、アドバイスをもらえないでしょうか。 parlでいうg修飾子はphpには無く、 例えば、[preg_match]は[preg_match_all]という関数で対応出来ますが、 置き換えを行う[preg_replace]には[preg_replace_all]がありません。 それに類する関数も無いように思います。 これに関して、PHPではどのように対応すれば良いのでしょうか。

    • ベストアンサー
    • PHP

専門家に質問してみよう