ブログを作る※無料・簡単アフィリ    ブログトップ | 楽天市場
137116 ランダム
「C++」はPHPの正規表現ではアウト… (パソコン・家電)楽天ブログ 【ケータイで見る】 【ログイン】
Google検索日記
ホーム 日記 プロフィール オークション 掲示板 ブックマーク お買い物一覧

PR

Calendar

November 2011
SMTWTFS
  12345
6789101112
13141516171819
20212223242526
27282930   
<一覧へthis monthnext>

Keyword Search

Category

Archives

Mobile

>>ケータイに
このブログの
URLを送信!

 

Google検索日記

<< 前へ次へ >>一覧

2004/08/08 楽天プロフィール Add to Google XML

「C++」はPHPの正規表現ではアウト?
[ web技術 ]    

AmazonのWEB Serviceを使って、ソフトウェアの販売ページをPHPとPostgresで作成しています。そこで、思わぬエラーが発生していることに今日になって気が付いた。

C++に関する製品を扱ったジャンル

Warning: eregi(): REG_BADRPT:・epetition-operator operand invalid in (PHPのパス) line 100

のようなエラーになっているではないですか?

エラーが発生している箇所はすぐに特定できました。先日、ジャンルを表示するアルゴリズムを修正したことが原因のようでした。eregi関数という正規表現を扱う関数を用いていたのですが、これが原因だと分かりました。

PHPの該当部分の問題点をハイライトするために、簡単な例題を書いてみますと、



<?php

$text_a = "プログラミング";

$text_b = "プログラミング→C・C++・C#";


header("Content-type: text/html; charset=EUC-JP");
if(eregi($text_a,$text_b,$regs)){
print "「" . $text_a . "」は「" . $text_b . "」に含まれます。<br>";
}

if(eregi($text_b,$text_a,$regs)){
print "「" . $text_b . "」は「" . $text_a . "」に含まれます。<br>";
}
?>


のようなプログラムがあった場合、このプログラムを実行した場合、どのような結果が表示されるでしょうか?

もちろん、
「プログラミング」は「プログラミング→C・C++・C#」に含まれます。

というのも表示されますが、そのほかに上述のwarningが表示されます。

これは、プログラムの10行目:
if(eregi($text_b,$text_a,$regs)){

に変数を代入してみると、原因がよく分かります。

if(eregi("プログラミング→C・C++・C#","プログラミング",$regs)){

となります。ところが、

eregi関数のマニュアル:
http://jp.php.net/manual/ja/function.eregi.php

にありますように、第一引数は「string pattern」(文字列の正規表現)であって、「string」(文字列)ではありません。ですから、第一引数に「+」があれば、それはメタ文字と解釈されてしまいます。

ですから、それ自体を検索させるためには、エスケープする必要があります。

if(eregi("プログラミング→C・C\+\+・C#","プログラミング",$regs)){

のようにすればOKです。ところが、先ほどの例題では、「+」は変数$text_bの中に含まれていて、変数の中身は事前には分からないので、エスケープしようがありません。そこで、苦肉の策ですが(もっと良い方法もあると思いますが)、

事前に、$text_b = eregi_replace("\+","あいうえおかきくけこ","$text_b");として、「+」を絶対に出現しない「あいうえおかきくけこ」という文字列に変換した上で、それを後で再変換する方法を取りました。




<?php

$text_a = "プログラミング";

$text_b = "プログラミング→C・C++・C#";


$text_b = eregi_replace("\+","あいうえおかきくけこ",$text_b);

header("Content-type: text/html; charset=EUC-JP");

if(eregi($text_a,$text_b,$regs)){
$text_c = eregi_replace("あいうえおかきくけこ","+",$text_b);
print "「" . $text_a . "」は「" . $text_c . "」に含まれます。<br>";
}

if(eregi($text_b,$text_a,$regs)){
$text_c = eregi_replace("あいうえおかきくけこ","+",$text_b);
print "「" . $text_c . "」は「" . $text_a . "」に含まれます。<br>";
}
?>


としました。

これで、Warningは表示されず、
「プログラミング」は「プログラミング→C・C++・C#」に含まれます。

だけがブラウザに表示されるようになりました。

決して、スマートな解決策でなく、以前会社勤めをしていて、これとよく似た処理を提案して、即刻、先輩社員に却下されたのを思い出しましたが、今回は、eregi関数の第一引数にくるものが何百とあるといっても、最初から候補(Amazonのジャンル名)は決まっていて、問題を起こすのが、「C++」の「+」だけであることが分かりましたし、フリーのプログラマーとして気楽にやっているため、これで良しとしました。


Last updated  2004/08/08 10:18:19 AM

[web技術]カテゴリの最新記事






<< 前へ次へ >>一覧一番上に戻る


Powered By 楽天ブログは国内最大級の無料ブログサービスです。楽天・Infoseekと連動した豊富なコンテンツや簡単アフィリエイト機能、フォトアルバムも使えます。デザインも豊富・簡単カスタマイズが可能!

Copyright (c) 1997-2012 Rakuten, Inc. All Rights Reserved.