php の正規表現について教えてください。


<jinriki>I have a <hatena q="1">question</hatena> to ask</jinriki>
のような文からタグを preg_replace でタグを取り除きたいのですが、うまくいきません。
q="1" の数字の部分は 1 以外の可能性もあります、2 桁以上の可能性もあります。

次のように記述しましたが
preg_replace(array("<jinriki>","</jinriki>","<hatena q=\"[0-9}*\">","</hatena>"),"",$text)
結果は次のようになりました
<>I have a <>question<> to ask</>

preg_quote を使うべきなのでしょうか?
対処法を教えてください。
PHP 5.3.0 です
よろしくお願いします。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2010/02/09 14:31:34
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:rouge_2008 No.1

回答回数595ベストアンサー獲得回数351

ポイント35pt

次のような感じでいかがでしょうか?

$text = '<jinriki>I have a <hatena q="1">question</hatena> to ask</jinriki>';
$text = preg_replace('/<.+?>/','',$text);
echo $text;

正規表現「<.+?>」で、「<」で始まり「>」で終わる任意の一文字以上の最短マッチになるようにすれば大丈夫です。

※タグの属性値をダブルクォーテンションで囲む場合となっています。

シングルクォーテンションの場合は、変数$textの方をダブルクォーテンションで囲んで指定してください。

id:Nigitama

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

今回は、<jinriki>, </jinriki>, <hatena q="1"> (数字は任意), </hatena> の 4 種類のタグのみを削除したかったのです。

それ以外のタグは残したいと思っています。

質問文が微妙でしたね。

のような文からタグを preg_replace でタグを取り除きたいのですが、

のような文から上記のタグのみを preg_replace でタグを取り除きたいのですが、

2010/02/09 11:07:45

その他の回答2件)

id:rouge_2008 No.1

回答回数595ベストアンサー獲得回数351ここでベストアンサー

ポイント35pt

次のような感じでいかがでしょうか?

$text = '<jinriki>I have a <hatena q="1">question</hatena> to ask</jinriki>';
$text = preg_replace('/<.+?>/','',$text);
echo $text;

正規表現「<.+?>」で、「<」で始まり「>」で終わる任意の一文字以上の最短マッチになるようにすれば大丈夫です。

※タグの属性値をダブルクォーテンションで囲む場合となっています。

シングルクォーテンションの場合は、変数$textの方をダブルクォーテンションで囲んで指定してください。

id:Nigitama

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

今回は、<jinriki>, </jinriki>, <hatena q="1"> (数字は任意), </hatena> の 4 種類のタグのみを削除したかったのです。

それ以外のタグは残したいと思っています。

質問文が微妙でしたね。

のような文からタグを preg_replace でタグを取り除きたいのですが、

のような文から上記のタグのみを preg_replace でタグを取り除きたいのですが、

2010/02/09 11:07:45
id:y-kawaz No.2

回答回数1422ベストアンサー獲得回数226

ポイント35pt

タグを取り除くだけなら strip_tags という関数があるのでこれを使ったらいかがでしょう?

http://php.net/manual/ja/function.strip-tags.php


正規表現でやる場合は以下で良いと思います。

preg_replace('/<.*?>/s', '', $text);
id:Nigitama

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

今回は、<jinriki>, </jinriki>, <hatena q="1"> (数字は任意), </hatena> の 4 種類のタグのみを削除したかったのです。

それ以外のタグは残したいと思っています。

質問文が微妙でしたね。

のような文からタグを preg_replace でタグを取り除きたいのですが、

のような文から上記のタグのみを preg_replace でタグを取り除きたいのですが、

2010/02/09 11:07:57

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 nzworks 13 12 0 2010-02-09 03:34:15
  • id:kn1967
    preg_系の関数はperlの文法に従うので、前後を囲む必要があり、
    おかしな結果になってます。

    それと余談ですが、ダブルクォーテーションで囲むと、
    phpによる変数展開によって、思わぬ結果になる場合がありますので、
    シングルクォーテーションで囲むほうが無難だったりしますし、
    展開すべきものがあるかどうかの確認などの作業もありませんので、
    処理的にも有利だったりします。

    >|php|
    $text = '<jinriki>I have a <hatena q="1">question</hatena> to ask</jinriki>';
    echo preg_replace(array('/<jinriki>/', '/<\/jinriki>/', '/<hatena.*>/', '/<\/hatena>/'), "", $text);
    ||<
  • id:rouge_2008
    > 今回は、<jinriki>, </jinriki>, <hatena q="1"> (数字は任意), </hatena> の 4 種類のタグのみを削除したかったのです。
    > それ以外のタグは残したいと思っています。

    そのケースも考慮すれば良かったですね。
    すみませんでした。(^-^;
    以下で大丈夫だと思います。

    $text = '<jinriki>I have a <hatena q="1">question</hatena> to ask</jinriki>';
    echo preg_replace(array('/<\/?jinriki>/', '/<\?hatena.*?>/'), "", $text);

    ※「<\?hatena.*?>」の「.*?」の部分が0文字以上の最短マッチとなっています。
    (最短マッチを使うと「<hatena q="1">」だけにマッチします。
    使わないと、「<hatena q="1">question</hatena>」までマッチしてしまいます。)

    確かにダブルクォーテーションだと展開されてしまうので、トラブルが起きる可能性も高くなりますね。
    なるべく使用しない方がいいのでしょうが、もし使用してエラーになった場合は、その辺りを疑ってみてください。
  • id:Nigitama
    kn1967 さん
    コメントありがとうございました。
    >preg_系の関数はperlの文法に従うので、前後を囲む必要があり
    これを知りませんでした。

    前後を囲んだら期待どおりに動作しました。

    rouge_2008 さん
    すいません、コメントに気が付かないうちに終了してしまいました。
    最短マッチの Tip もありがとうございます。
    後付ですが、イルカショウを進呈いたします。
  • id:kn1967
    phpの正規表現は以下の二種類
    perl 互換 http://jp.php.net/manual/ja/book.pcre.php
    POSIX 拡張 http://jp.php.net/manual/ja/book.regex.php

    perl互換のほうが全般的に高速。perlとは一部違うので、
    両刀使いの場合はちょっと注意が必要(詳細は上記リンク先から参照)
    POSIX 拡張はphp次回メジャーバージョンアップでは削除される予定で、
    php5.3.0以降は非推奨となっている。

    以上、蛇足。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません