人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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

現在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;
}

●質問者: oboist
●カテゴリ:インターネット ウェブ制作
✍キーワード:JIS STR XFC エラー コード
○ 状態 :終了
└ 回答数 : 5/5件

▽最新の回答へ

1 ● noocyte
●30ポイント

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

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

 大 き い
C2E7 A4AD A4A4
 ~~~~~

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


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

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

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

[\xA1-\xFE]

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

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

◎質問者からの返答

noocyteさま

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

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


2 ● Yota
●10ポイント

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

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

◎質問者からの返答

Yotaさま

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

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


3 ● noocyte
●40ポイント

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

あ,えーと,[\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}
◎質問者からの返答

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;

}


4 ● Yota
●10ポイント

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

$reg = "[?-?≒≡∫??√⊥∠??∵∩∪]" ;

参照したページ

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

◎質問者からの返答

Yotaさま

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

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

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


5 ● Yota
●10ポイント

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

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

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

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

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

Multibyte (japanese) regex support enabled

になっていますか。

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

◎質問者からの返答

Yotaさま

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

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

Red Hat Enterprise Linux Server release 5

Apache 2.2.4

PHP4.4.7

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

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

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ