Perlでフォームに入力された値をチェックするとき、入力される文字列は半角文字以外を入力されるとエラーになるスクリプトを書きたいと思っています。
(ただし、半角に出来る文字「カタカナ、記号等」は半角に変換するのでエラーでは無いとしたいです)

どうすれば実現出来るでしょうか。
よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

パターンマッチを利用することをオススメします。


とりあえず、余計なマッチミスを防ぐためにも、EUCコードに変換してから処理を行います。
参考URLのページに詳しく解説されています。
参考URLのページをみても分からなければ、補足をお願いします。

一応、主要な文字コードのパターンを記しておきます。
$nobashi = '(?:\xA1[\xBC\xBD\xC1])'; # ー-~
$kigo = '(?:[\xA1\xA2][\xA1-\xFE])'; # 全角の記号
$suuji = '(?:\xA3[\xB0-\xB9])'; # 0-9
$alphabet = '(?:\xA3[\xC1-\xDA\xE1-\xFA])'; # 全角英字
$alpha_big = '(?:\xA3[\xC1-\xDA])'; # 全角英字(大文字A-Z)
$alpha_small = '(?:\xA3[\xE1-\xFA])'; # 全角英字(小文字a-z)
$hiragana = '(?:\xA4[\xA1-\xF3])'; # ぁ~ん
$katakana = '(?:\xA5[\xA1-\xF6])'; # ァ~ヶ

参考URL:http://www.din.or.jp/~ohzaki/perl.htm

この回答への補足

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

参考URLを見てやってみたのですがうまくいきません。
カタカナが1文字の時はうまく行くようなのですが、複数のカタカナになった場合、失敗します。
文字コードは全てEUCで行っています。

以下がやろうとしている手順です。

1.全角文字を半角文字へ変換する

2.チェックを行う

#1バイト文字以外の時
if($buf !~ /[\x00-\x7F]/){
  #半角カタカナ以外のとき
  if($buf !~ /(?:\x8E[\xA6-\xDF])/){
    print "NG\n";
    exit;
  }
}
print "OK\n";

どこがおかしいのでしょうか。
正規表現はまだよく分かっていないためご迷惑をおかけしますがよろしくお願いします。

補足日時:2002/01/22 09:17
    • good
    • 0

参考URLの「日本語を扱う」の項の「正しくパターンマッチさせる」の部分を読まれたでしょうか?


http://www.din.or.jp/~ohzaki/perl.htm#JP_Match

私もこのページにはよくお世話になります(^^;
ここに書かれたとおり、文字コードを指定するだけではうまく行かないのです^^;

後、前の書き込み時には忘れていたのですが、
私の書いた全角の記号には半角に変換出来ない記号も含まれます。とりあえず、文字コードを調べられるソフトで変換の対象にしたい文字のコードを調べてください^^;
私は プレジャースカイという会社の フリーソフトhttp://www.pleasuresky.co.jp/ を使わせて頂いてます。

>修飾子 g (処理の対象を全域にする)を使ってください
は単に含まれるかを調べる場合、必要ありません。
abc に b というパターンがマッチします。
perl -e "$str='abc'; print 'Match!' if $str =~ /b/;"
プロンプトから実行してみてください。
「プロンプト」というのは、ちなみに、Win9X系だと、DOSプロンプト、WinNT系だと、コマンドプロンプトと呼ばれる物です。Linuxだったらターミナル(エミュレータ)です。念のため^^;

参考URL:http://www.din.or.jp/~ohzaki/perl.htm#JP_Match, http://www.pleasuresky.co.jp/

この回答への補足

回答ありがとうございます。
下で書いたコードですが間違っていたようです。
みなさんのアドバイスを受けながらいろいろ考えてみたのですがとりあえず、以下のコードでうまく動いているようです。

sub Check{
  ($buf) = @_;

  #1バイト文字を消す
  $buf =~ s/[\x00-\x7F]//g;
  #半角カタカナを消す
  $buf =~ s/(?:\x8E[\xA6-\xDF])//g;
  #まだ文字が残っていればエラーとする
  if(length($buf) == 0){
    return "OK";
  }else{
    return "NG";
  }
}

感覚的にあまりよい回答では無いと思うのですが。
もし、もう少しよい回答があれば教えていただけるとうれしいです。

補足日時:2002/01/23 10:36
    • good
    • 0
この回答へのお礼

> 参考URLの「日本語を扱う」の項の「正しくパターンマッチさせる」の部分を読まれたでしょうか?

読ませていただきました。
難しいですね。文字の奥の深さが分かります。
少しずつ理解していきたいと思います。
[g]の件もありがとうございました。

これからも質問等するかもしれませんがよろしくお願いします。

お礼日時:2002/01/23 11:09

全角カナと半角カナの並びは違うので、変換しようと思ったらパターンを配列に記述するしかないと思います。


私は逆のこと、つまり半角カナを全角カナに直すとか勉強してました。

$moji = 'ホゲ';

@base = ('ア', 'イ',・・・'ァ'・・・);
@change = ('ア', 'イ',・・・'ァ'・・・); #←ホントは半角

for($n = 0; $n < @base; $n++){
$moji =~ s/$base[$n]/$change[$n]/g;
}

とかやってできると思ったら、大間違いでした!
ある文字の2バイト目と次の文字の1バイト目を1文字としてマッチしてしまうのです。
難しいところです。
ほかの方の参考URLなどもみて、お互いがんばって勉強しましょう。

ちなみに、このOKWEBも指摘するように、半角カナは機種依存文字なので使わないほうがいいです。
半角って言ってもEUCでは2バイトだし・・・。
    • good
    • 0
この回答へのお礼

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

半角カタカナはWebでは使わない方がいいのは分かっているのですが、プログラムの仕様上どうしても半角カタカナを使用しなければいけないんです。

上に作成してみたコードを書いておきました。
もし、アドバイス等ありましたらよろしくお願いします。

お礼日時:2002/01/23 10:46

修飾子 g (処理の対象を全域にする)を使ってください。


if($buf !~ /(?:\x8E[\xA6-\xDF])/g){
とします。

正規表現には修飾子の他量指定子、位置指定子など、
色々ありますので、一度ネットや本で調べると面白いです。

私も、正規表現では苦労しています。頑張りましょう。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
上の記事に考えてみたコードを書いておきました。
また、おかしいところ等あればアドバイスよろしくお願いします。

正規表現は難しいですね。
でも、面白いものだとも思います。
がんばりたいと思いますでこれからもよろしくお願いします。

お礼日時:2002/01/23 10:43

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q正規表現のAND条件記述手法

お世話になります。
正規表現でAND条件を実現したいのですがうまくいかないでいます。

以下のような任意の文字列
1234567890

があったとして、3~5を抜き出したい時の正規表現は
[3-5]
とすると、そこへ6も対象に入れたいとなれば
[3-5]|6
とすればOR条件でいけると思います。

この逆といいますか、AND条件のように記述したいのですが、
3~5だけど、4はやっぱ含まないというのはどのように表記するのか
手法を教えて頂けたらとおもいます。
[3-5]&[^4]  ???。。

(単純に[3,5]とすれば良いのでしょうが、もっと複雑な表現に応用を考えてます)

宜しくお願い致します。

Aベストアンサー

#4でなくて3-5
$text="1234567890";
while($text =~ /(?=(?!4))[3-5]/g){
print $&;
}

QJcodeモジュールを使うのが定石でしょうか? 半角カタカナ→全角カタカナ変換

perlで半角カタカナを全角に変える場合、Jcodeモジュールを使いますが、現在ソースでuse utf8を使っているので、すべて use Encodeのモジュールで半角カタカナを全角カタカナに変えることがしたいのですが、Jcodeモジュールを使うのが定石でしょうか?

Aベストアンサー

Jcode が一般的だと思います。自作するのも手ではありますが、大変だと思います。

Q正規表現でAND検索はできるのでしょうか

正規表現でAND検索はできるのでしょうか?

現在ASPでデータベースのデータを検索しようとしているのですが,検索エンジンみたいに複数の語をスペースで区切って入力して,データを絞り込んで表示したいのです。

OR検索みたいにそれぞれの語を"|"でつなぐというようなやり方があるのでしょうか?
それとも一つ一つの語で検索を繰り返すという方法しかないのでしょうか?

ご存知の方,ご教授ください。

Aベストアンサー

&&でつながれたらいかがですか?

(?=.*stat)(?=.*ate)はAND検索という意味ではありません。
statedのようにstatとateを重複して含む単語にマッチするという意味です。

普通はこんな回りくどいことはせず、
/stat/ && /ate/
で済ませると思います。
(もしくは単純にループでまわしていくとか)


foo.*bar|bar.*foo
も、2語程度までが限界ですよね。
10語分繋げることを考えると気が遠くなります。
(記述も処理時間も)

言語によってはさらに処理を短縮できるような
特有な構文がありますから、調べてみればよろしいかと思います。

QPerlで半角英数字以外の入力を拒否するには

全く想像がつかないので、ご回答お願いいたします。

現在Perlで簡単なプログラムを作成しているのですが、全角で何かを入力するとプログラムがフリーズしてしまいます。これを防ぐために、半角の英数字以外の入力をシャットアウトしたいのですが、その判定をするにはどういうプログラムを入れればよいでしょうか。

データはPOSTで送っており、運用上、全角文字だけでなく、できれば半角カナも排除したいのですが……。
よろしくお願いいたします。

Aベストアンサー

$strに半角英数字以外の文字が含まれたらexitするコードはこんな感じです。
改行もスペースも@なんかもexitされますのでご注意。

if ($str =~ /[^0-9A-Za-z]/) {exit;}

ただ、フリーズするということはどこかに地雷が眠っているということでもあるので、これを機会にどこでフリーズしているかは調べておいたほうが良いですよ。地雷を踏ませないようにするよりも、地雷そのものを処置したほうが安心ですし。

Q任意の回数出現する正規表現について

PHP Version 5.3.1
を使用しています。

次のような2パターンの文字列が与えられた場合に、

fetchAllWithUser ← Userを取得したい
fetchAllWithBlogAndCommentAndImg ← BlogとCommentとImgを取得したい

fetchAllWithの後の任意の文字列(Andは除く)を1つの正規表現の記述で取得したいのですが、
どのような正規表現にすれば良いのでしょうか?

Aベストアンサー

正規表現にする必然性がないのでは?

$arr = array();
if (substr($str, 0, 12) === 'fetchAllWith') { $arr = explode('And', substr($str, 12)); }

QPerlスクリプトで文字化けしてしまう

Perlの初心者向けの本を見ながら勉強を進めているのですが、途中で文字化けしてしまい、解決方法もその本には書かれていないので困っています。環境はWindowsです。

以下のスクリプトを実行すると、

$string = 'あいうえお';
$string =~ tr/あ/い/;
print "$string\n";

以下の様な結果になります。これは問題ありません。

いいうえお

しかし、「い」に変換する所を、「イ」に変換する様に書き換えた、以下のスクリプトを実行すると、

$string = 'あいうえお';
$string =~ tr/あ/イ/;
print "$string\n";

以下の様に、文字化けした結果になります。

イΔΖΘΚ

WEBで調べ、いくつか処理を追加したりしてみたのですが、エラーが出るだけで解決しませんでした。

文字化けする理由と対処法をご存知の方がおられましたら、お教え頂けないでしょうか。

Aベストアンサー

スクリプトの先頭に以下の4行を追加して、文字コードutf-8で保存してみてください。
use utf8;
binmode STDIN, ':encoding(cp932)';
binmode STDOUT, ':encoding(cp932)';
binmode STDERR, ':encoding(cp932)';

windowsで普通にスクリプトを保存するとshift_jis(正確にはcp932)とう文字コードで保存されます。
ところがperlは、文字コードutf-8で書かれていると思って処理しますのでcp932で書かれたスクリプト内の文字定数は正しく認識されずに誤動作します。したがってスクリプトをutf-8で保存する必要があります。

さらにコマンドプロンプトはcp932で文字を表示しますので、perlで文字出力する場合にはutf-8をcp932に変換してあげる必要があるのです。


参考にされている書籍に上記の注意がないということは、古いバージョンのperlを前提に書かれているものと推察されます。

外部ファイルの読み書きで日本語を使用する場合にも同様の処理が必要になりますので注意が必要になると思います。

スクリプトの先頭に以下の4行を追加して、文字コードutf-8で保存してみてください。
use utf8;
binmode STDIN, ':encoding(cp932)';
binmode STDOUT, ':encoding(cp932)';
binmode STDERR, ':encoding(cp932)';

windowsで普通にスクリプトを保存するとshift_jis(正確にはcp932)とう文字コードで保存されます。
ところがperlは、文字コードutf-8で書かれていると思って処理しますのでcp932で書かれたスクリプト内の文字定数は正しく認識されずに誤動作します。したがってスクリプトをutf-8で保存する必要があり...続きを読む

Qrubyの正規表現について質問です。

rubyの正規表現について質問です。

rubyを勉強中ですが、
正規表現について質問させてください。

以下のようなことをしたいのですが、どのような記述をすれば実現できるでしょうか?

(1)test → #test
(2)test → test


「test」の場合は、「#」を加え、「#test」に置換したい
「test」の場合は、そのまま「test」としたい。

if を続ければ可能だとは思いますが、
一つの正規表現で(1)のケースだけを引っ掛けられればと思っています。

正規表現でANDが使えればよいのですが、使えないようですし。。。


お手数をおかけしますが、お力をよろしくお願いします。

Aベストアンサー

違いが全く分かりませんが、
例えば、
test→#test
#test→#test
として出力したい場合以下のようにすれば可能です。参考になればですが・・。
str.gsub(/(?<!#)(?=test)/,'#')

Qperlにてフォームに入力したhtmlの<>タグの外の半角スペース削除

perlにてフォームに入力したhtmlの<>タグの外の半角スペース削除
よろしくお願い致します。
Perlのバージョンは[5.10.0]です。
下記の様なhtmlから<>の外側の半角スペースを削除する方法を教えて下さい。
<>の外側でスタイル指定部分の半角は残す必要があります。
<style type="text/css">
<!--
#container{*****}
h1{border-right:solid #e4dac6 2px;} #<---この部分の半角スペースは残す必要があります。
.discript0 { margin:0;}
#col_1{****}
-->
</style>
<div id="container">

<h1>** ***</h1>#<---<h1>の前の部分の半角スペースは削除。
<div id="col_1">
<p class="discript0">
123123 121 23#<---「123123 121 23」の「123123」の前と「121 23」の間の半角スペース削除。
</p>
</div>
</div>
htmlのbodyに組み込む部分です。
ご回答頂くにあたり必要事項の追加が必要で有ればご指摘下さい。
よろしくお願い致します。
確認するボタンを押すと、自動的に「<」の前のスペースとタブが削除されて表示していますが、
記入時は「<」の前にはタブと半角スペースがあります。

perlにてフォームに入力したhtmlの<>タグの外の半角スペース削除
よろしくお願い致します。
Perlのバージョンは[5.10.0]です。
下記の様なhtmlから<>の外側の半角スペースを削除する方法を教えて下さい。
<>の外側でスタイル指定部分の半角は残す必要があります。
<style type="text/css">
<!--
#container{*****}
h1{border-right:solid #e4dac6 2px;} #<---この部分の半角スペースは残す必要があります。
.discript0 { margin:0;}
#col_1{****}
-->
</style>
<div id="container">

<h1>** ***</...続きを読む

Aベストアンサー

>上記の内容は$html =~ s#AAAA#BBBB#egs;と理解すれば良いのでしょうか?
はい、そうです。
一般的にs///の形式で用いられる区切り文字を#にしたものです。

{ と } が単独で使われると消失するというバグを発見したので以下に修正させてください。

$html =~ s#((?<=<style type="text/css")>\n*<!--.+-->\n*(?=</style>)|>.+?<)#
join q{}, map { /^{.+}$/s or tr/ \t//d; $_ } $1 =~ /{.+?}|[^{}]+|[{}]/gs;
#egs;

上記コードを分かりやすく分解しました。
参考にしてください。

$html =~ s#((?<=<style type="text/css")>\n*<!--.+-->\n*(?=</style>)|>.+?<)#
my @matched_strings = ( $1 =~ /{.+?}|[^{}]+|[{}]/gs );
my @trimmed_strings = map { /^{.+}$/s or tr/ \t//d; $_ } @matched_strings;
my $trimmed_string = join q{}, @trimmed_strings;
#egs;

実は本日より2~3ヶ月入院します。
そのため、追加質問されましても回答できませんので、もし、上記コードが分かりにくければ、新たに質問を立ててください。

>上記の内容は$html =~ s#AAAA#BBBB#egs;と理解すれば良いのでしょうか?
はい、そうです。
一般的にs///の形式で用いられる区切り文字を#にしたものです。

{ と } が単独で使われると消失するというバグを発見したので以下に修正させてください。

$html =~ s#((?<=<style type="text/css")>\n*<!--.+-->\n*(?=</style>)|>.+?<)#
join q{}, map { /^{.+}$/s or tr/ \t//d; $_ } $1 =~ /{.+?}|[^{}]+|[{}]/gs;
#egs;

上記コードを分かりやすく分解しました。
参考にしてください。

$html =~ s#((?<=<s...続きを読む

Q言語ではなく、正規表現のみで複数の条件を記述する方法 ?

一つの条件の正規表現は書けるようになりましたが、
条件が重なった場合の対処の仕方がわかりません。

my $val = "12";
#数字のみ
if($val =~ /^[0-9]+$/){
# match!
}

#0で無い
if($val !~ /^0$/){
# match!
}

# 数字で0でない <---複数条件



# 言語でカバーするのではなく、正規表現のみ(1つの正規表現)
# でANDやORやXORができるパターンの記述方法が知りたいです。
if($val =~ /^[0-9]+$/) && ($val !~ /^0$/){
# match!
}

Aベストアンサー

条件式の AND や XOR に相当するものは、正規表現には存在しません。というのも、正規表現で表すのは「パターン」であり、「条件」ではないからです。
※OR についてはパターンの選択を行う | が相当します。

このため、複数の条件式にしたくない場合は、1つで複数の条件を満たすパターンを書くしかありません。また、汎用的な方法もないので、ケースごとにパターンを書き下ろさなければなりません。

No.2 補足より
> 言語を使った&& ||ではスマートではなく、複雑な内容になってきた場合、1行で解決できた方が発展性があるかと思いましてこだわっております。

確かに「0ではない数字」程度のことを複合条件にするのはスマートとは言えないでしょう。しかし、関連性のない事柄を無理なパターンで表現するくらいなら、分解して && や || で結合した方がすっきりします。
また、大概の場合、1行で無理に解決した方が発展性には欠けますので、発展性やメンテナンス性を求めるならば、あまりこだわらない方がよいでしょう。

Qperl-cgiで1文字や2文字など短い、文字コードを正しく変換したい

一文字や、2文字の短い文字コードを正しく変換したいのですが何か、良い方法は無いでしょうか?
文字コードには、絶対に、SJISかUTF8のどちらかしか使っていません。
どなたか、お分かりになる方、教えていただけないでしょうか?
よろしくおねがいいたします。

Aベストアンサー

何文字であっても Encode の from_to を使えばいいと思います。



use Encode 'from_to'; # プログラムの最初の方でこれをやっておく。

# 実際に使いたい所でこれをする(この場合はShift_JISからutf8への変換)。
from_to($str, 'Shift_JIS', 'utf8');
# この後は $str の内容がutf8になっている。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング