お世話になっております。


現在preg_match_all関数を使って正規表現で機種依存文字(まずはJISコード13区に当てはまる文字)があるかどうかをチェックするロジックを作っているのですが、「大きい」などを機種依存文字(この場合は丸付き数字の4)と解釈したり、機種依存文字が1つだけなのに、エラーとして返される文字列になぜか2つ入っていたりと、いろいろと問題が多く困っています。

以下、簡単にコードを示しますので、問題点をご教示いただけるとありがたいです。なお、「きい」のところを機種依存文字(丸付き数字など)にしてチェックしていただければ、なおありがたいです。

$str = "きい";
if(preg_match_all("/([\xAD][\xA1-\xBE\xC0-\xD6\xDF\xE0-\xFC])/",$str,$ary)){
$err_flg = FALSE;
$err_ary = $ary;
}

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

回答5件)

id:noocyte No.1

回答回数21ベストアンサー獲得回数3

ポイント30pt

正規表現が,2バイト文字の第2バイト以後のバイト列とマッチしています.

そうならないようにしなきゃ.

 大   き   い
C2E7 A4AD A4A4
       ~~~~~

PHP は使ったことがないので,解決策については PHP ユーザにまかせます.


ところで,2バイト目の正規表現が

[\xA1-\xBE\xC0-\xD6\xDF\xE0-\xFC]

となってますが,13区はこれ以外の部分はすべて未定義なので,

[\xA1-\xFE]

として13区皆殺しでいいと思います.

(それとも,未定義の2バイト文字はあっても無視したい?)

id:oboist

noocyteさま

ご回答、ありがとうございます。記述した正規表現は、翔泳社の正規表現辞典に従った記述です。

ただ、preg_match_all("/[\xAD][\xA1-\xFE]/",$str,$ary)に変えてみましたが、残念ながら状況は変わりませんでした(エラーとして返される文字列は期待通りになりましたが)。

2007/09/07 16:08:35
id:Yota No.2

回答回数453ベストアンサー獲得回数28

ポイント10pt

マルチバイト文字列関数を使う。ひたすら候補を並べる。

mb_regex_encoding('EUC-JP') ;

$str = "①からい②あまい③すっぱいⅠⅡ㈱大きい㈲";

$reg = "[①-⑳Ⅰ-Ⅹ㈱㈲㈹]" ;

mb_ereg_search_init($str, $reg);

$r = mb_ereg_search();

if($r) {

$r = mb_ereg_search_getregs();

do {

print_r($r[0]);

$r = mb_ereg_search_regs();

}

while($r);

}

参照したページ

http://www.php.net/manual/ja/function.mb-ereg-search.php

id:oboist

Yotaさま

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

今回はpreg_match_all関数を使いたいので、この回答は後学のために参考にさせていただきます。

2007/09/07 18:18:06
id:noocyte No.3

回答回数21ベストアンサー獲得回数3

ポイント40pt

> 残念ながら状況は変わりませんでした

あ,えーと,[\xA1-\xFE] の件は解決策として書いたのではなくて,

単に13区の判定を簡単にするだけの意味で提案したものです.


… とだけ書くのも気がひけるので,ちょっと PHP の正規表現を

調べて解決策を考えてみました.


┌これでどうでしょうか?

│ (読みやすいように改行&インデントしていますので,

│ 空白を削除して1行につなげてください.

↓ 動かしてないんでちゃんと動くかどうかわかりません.)

"/^(?:
    [\x01-\x7F]|
    [\xA1-\xAC\xAE-\xFE][\xA1-\xFE]|
    (\xAD[\xA1-\xFE])|
    \x8E[\xA1-\xDF]|
    \x8F[\xA1-\xFE]{2}
)*$/"

各行の意味は次のとおりです.

ASCII:[\x01-\x7F]
JIS X 0208 (13区以外):[\xA1-\xAC\xAE-\xFE][\xA1-\xFE]
JIS X 0208 (13区のみ):\xAD[\xA1-\xFE]
JIS X 0201 半角カナ:\x8E[\xA1-\xDF]
JIS X 0212/0213 補助漢字:\x8F[\xA1-\xFE]{2}
id:oboist

noocyteさま

再度のご回答、ありがとうございます。

教えていただいたコードを参考に、下記のようなコードに作り直しました。おかげさまで、機種依存文字は除外できたのですが、preg_match_allに!をつけてしまったため、エラーとなった文字が取得できなくなってしまいました。パターンを否定できればいいのですが、その方法がどうしても見当たらず困っています(/^$pattern/が否定だと思ったのですが、ダメでした)。

$str="○13(丸付き数字の13)"

$pattern = "/^([\x01-\x7F]|[\xA1-\xAC\xAE-\xFE][\xA1-\xFE]|[^[\xAD][\xA1-\xFE]]|[\x8F][\xA1-\xFE]{2})*$/";

if(!preg_match_all($pattern,$str,$ary)){

  $err_flg = FALSE;

  $err_ary = $ary;

}

2007/09/07 18:24:36
id:Yota No.4

回答回数453ベストアンサー獲得回数28

ポイント10pt

2回答者です。訂正します。こういう正規表現でどうでしょう。

$reg = "[①-㍼≒≡∫∮∑√⊥∠∟⊿∵∩∪]" ;

参照したページ

http://www2d.biglobe.ne.jp/~msyk/charcode/kisyuizon/13-14ku.html

id:oboist

Yotaさま

再度のご回答、ありがとうございます。

早速試してみたのですが、残念ながら期待した結果は得られませんでした。

こちらももっと勉強しますので、もし妙案が見つかりましたら、ぜひアドバイスをお願いいたします!

2007/09/07 19:06:31
id:Yota No.5

回答回数453ベストアンサー獲得回数28

ポイント10pt

早速試してみたのですが、残念ながら期待した結果は得られませんでした。

そうですか。わたしのほうは元気よく拾えていますが。

テキストエディタとmb_regexエンコーディング指定は同じですか。

といってもWindows+PHP5だから、環境が違うのかもしれません。

phpinfo();のmbstringのところで、

Multibyte (japanese) regex support enabled

になっていますか。

UNIXの場合は、enable-mbregexとかしてコンパイルしないとだめかも知れません。

id:oboist

Yotaさま

再度のご回答、ありがとうございます。

記載し忘れていましたが、当方の環境は以下の通りです。

Red Hat Enterprise Linux Server release 5

Apache 2.2.4

PHP4.4.7

また、最初に記載した通り、今回はpreg系関数を使いますので、mb_ereg系は使用しません。ご了承ください。

少し光明が見えてきたので、いったん質問をcloseして、また別の形で質問させていただきます。

2007/09/10 15:51:02

コメントはまだありません

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

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

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

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