トップページ⇒php
825コメント240KB

正規表現道場@2ch Part2

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん02/11/24 22:57ID:LrbVcl3Y
Perlに限らずスクリプト系言語で大活躍の正規表現。
このスレは有用そうな正規表現を紹介したり、どう表現したらいいかわからないときに
質問をしたりするためのスレッドです。
質問するときは使用言語や得たい結果をなるべく詳しく書きましょう。

リンクなどは>>2-5のあたりに。
0413nobodyさん03/04/26 00:57ID:IuuTGNpA
/.+@[a-z0-9]+.[a-z]+/

メアドの正規表現ってこんな感じでいいの(初心者でつ)?
0414nobodyさん03/04/26 01:10ID:???
>>413
メールアドレスを完璧に表すのは難しいぞ
このスレを少し遡れば同じ話題あるよ
0415nobodyさん03/04/26 13:56ID:???
まだこっちのほうが良くないか?

[^@]+@[a-zA-Z0-9\-_]\.[a-z]{,3}
0416nobodyさん03/04/26 19:14ID:???
/^[^\@]+\@(?:[0-9a-z_-]+\.)+[a-z]{2,4}/i
0417nobodyさん03/04/26 19:26ID:???
>>416
TLDは4文字以上も予定されているよ
0418nobodyさん03/04/26 19:28ID:???
日本語ドメインはどうすんの?
0419nobodyさん03/04/26 20:02ID:???
>日本語ドメイン
無かった事にしてくれ。
(でも、確かRFC的には許容内なんだよな。鬱)
0420nobodyさん03/04/26 21:59ID:???
メールアドレスを正規表現でと言っても用途にもよるんだよな。
RFCに適合するかどうかのチェックなら厳密にやらなければならないし、
実際には許されない架空のアドレス風味を表すだけなら簡単だし。
0421nobodyさん03/04/27 01:10ID:???
/\@/; #完璧!
0422nobodyさん03/05/07 01:48ID:U7blGvbH
JavaのOROのPerl5Utilを使っています。
基本的には\が重なること以外にはPerl5と同じはずです。

これ↓を
SELECT * FROM MEMBER WHERE {NAME='[personName]' AND }AGE=[age]{ AND TEL='[tel]'} ORDER BY AGE;

こういう風に
SELECT * FROM MEMBER WHERE AGE=[age]{ AND TEL='[tel]'} ORDER BY AGE;

変換したいのですが下記ではだめなのでしょうか。

/\\{.*?\\[personName\\].*?\\}//
0423nobodyさん03/05/07 02:05ID:???
>>422
いいでつ。
0424nobodyさん03/05/07 03:09ID:???
メールアドレスなら
@よりもあとを正引きしてMXレコードがあるかどうか
調べるとかどう?
0425nobodyさん03/05/07 03:11ID:???
正引きする必要はないか
MXレコードがあるかどうかだけ調べてみるとか
DNS鯖とか落ちてたら登録拒否できるから
確認のメール送る場合とか結構有効じゃない?
0426nobodyさん03/05/07 07:37ID:???
>>422
黙って移動してくんなバカ
0427見習い中03/05/07 09:46ID:l7Gf5uMD
突然の質問で恐縮です・・・

今、正規表現を使って半角英数字のチェックを行っているのですが、
入力テキストエリアに半角英数字が入力されたら、エラーを出すように
したいのですが、

if ($in{'name'} !~ /[a-zA-Z0-9\-]+/ ) { &error("エラーです"); }

としたところ、半角英数字はエラーを返すのですが、
全角英字大文字(ABC)と全角数字(123)も反応してしまいます。
(ToT)...
全角英字小文字(abc)は反応しませんでした。。

半角英数字の入力のみエラーを返したいのですが、どなたか教えてください。
0428あぼーんNGNG
あぼーん
0429nobodyさん03/05/07 10:52ID:???
>>427
もしかしてAだけの入力ならうまく動作しませんか?
バイナリエディタを使ってABC周辺のバイトコードと
abc周辺のバイトコードを比較してみましょう。
043042703/05/08 12:05ID:0MiTKfYx
レスありがとうございます。。
いろんなサイトを調べてみたら、こんなのがあってやってみました。

jcode::convert(\$in{'name'}, 'euc');

if ($in{'name'} !~ /^[\xA1-\xFE][\xA1-\xFE]+$/ ) { &error("エラーです"); }

とやったら、うまくいきました。(全角文字以外はエラーを返します。)
jcode.plの力ということでしょうか。。。プログラムは奥がふかいです。。。
0431nobodyさん03/05/09 22:56ID:???
>>430
EUC-JPの力です。
0432nobodyさん03/05/10 18:06ID:/HHBMizp
すみませんが質問させてください。

ニュースサイトからアンカータグの部分だけを取得してくるスクリプトを
書いていたのですが、htmlソースの一行の中に複数のアンカータグがあった場合、
その全てをきれいに抽出できないのです。例えば、抽出したい元のソースが

<a href="http://aaa.com/">あああ</a>、<a href="http://iii.com/">いいい</a><br>

のようになっていたとして、正規表現でそれぞれのタグにマッチングさせようとしても何故か

『<a href="http://aaa.com/">あああ</a>、<a href="http://iii.com/">いいい</a>』か、
『<a href="http://iii.com/">いいい</a>』だけか、
『<a href="http://aaa.com/">あああ</a>』だけといったようにしか抽出できず、
純粋に
『<a href="http://aaa.com/">あああ</a>』と『<a href="http://iii.com/">いいい</a>』
の2つを取り出せないのです。

拙いながらこのようなことを散々試したのですが……。
while( $list =~ /<a\s.*href="{1}?.*"{1}?.*>{1}?.*<\/a>{1}?/g )
{
print $&;
}

どなたか、助言していただけませんでしょうか。
043343203/05/10 18:09ID:???
自動リンクでなんかアホなことになってしまった。すみません……。
0434nobodyさん03/05/10 19:16ID:???
根本的なセンスが感じられないな
0435nobodyさん03/05/10 19:44ID:???
>>432
マイナス25点ってとこだな。なぜマイナスかと言うと、使うと損するくらい
まともに処理できてないからな。

まア、80点以上が出たらわたしのほうから正解を書くとしよう。
0436nobodyさん03/05/10 20:18ID:???
確かにセンスなさげだ
0437nobodyさん03/05/10 20:32ID:???
>>432
String#scan 使うとめっちゃ簡単に書けるよ。
0438nobodyさん03/05/10 20:33ID:???
>>437
Ruby 厨 キタ━━━━━━(゚∀゚)━━━━━━ !!!!!
0439nobodyさん03/05/10 22:59ID:???
>>437
やってることは同じだし、正規表現を使わないといけない所も同じ。めっちゃって言うほど簡単になるか?
0440nobodyさん03/05/10 23:28ID:???
これでええやん。堕落かもしれないけど。

HTML::LinkExtor->new(
sub {
 my ($tag, %attr) = @_;
 push @links, values %attr;
}
)->parse(\$list);

print "$_\n" foreach @links;
0441nobodyさん03/05/10 23:40ID:???
正規表現版は、とりあえず、、
print "$1,$2\n" while $list =~ m#<a href="([^"]+)">([^<]*)</a>#ig;
これで妥協して。
0442nobodyさん03/05/11 00:24ID:???
href=''の場合もあるとか言いたいけど、我慢。
0443nobodyさん03/05/11 00:41ID:???
<a hoge='hoge href="http://"' href = 'http://'>;<!-- hogehoge </a> -->hogehoge</a>の場合も…略
044443503/05/11 01:12ID:???
>>441
まア、それでも60点ってとこだな
0445センスのない43203/05/11 07:00ID:???
>441氏(神)のやつを参考にしたところ、うまくいった模様です。
name="" id="" class="" target="" 等が入った場合にも対応できたので、
とりあえずこれで良しとします。ありがとうございました。>434-444
044640503/05/11 10:38ID:QXPmJshp
ケツの</a>みてないけど、
m#<a.+?\s*href\s*=.+?\s*>#ig
あたりでどう?

<a name="" target="" href="http://hoge">
ってケースもある。
044743503/05/11 11:05ID:???
>>446
50点ってとこだな
0448nobodyさん 03/05/11 12:33ID:???
http_regx使っていいの〜?
0449nobodyさん03/05/11 14:25ID:QXPmJshp
>>448
いいよ
0450nobodyさん03/05/11 15:26ID:???
open FILE, $file or die $!;
read(FILE, $doc, -s FILE);
while( $doc =~ m|<a.*?/a>|isg ){
my $temp = $MATCH;
$temp =~ s/\n//g;
print $temp,"\n";
}

close FILE;
045143503/05/11 16:12ID:???
>>450
<applet><a href="hoge">abc</a>
<address><a href="hoge">abc</a>
<area><a href="hoge">abc</a>

あらゆる可能性も考慮しないと・・・30点
0452nobodyさん 03/05/11 16:24ID:???
{
  my @tag = $_ =~ m/<a([^>]).>/g;
  @uri = map{ m/($http_regx)/; $1; } @tag;
}

$http_regxは自分で調べること
0453nobodyさん 03/05/11 17:16ID:???
>>452訂正
{
  my @tag = $data =~ m/<a([^>].)>/g;
  @uri = map{ m/($http_regx)/; $1; } @tag;
}
0454nobodyさん03/05/11 17:23ID:???
<a [^>]*href=("[^"]+:[^"]+"|'[^']+:[^']+')[^>]*?>
045543503/05/11 17:28ID:???
>>454
 >>451も読んでね。

>>452,>>453は問題外
0456nobodyさん03/05/11 17:45ID:???
>>450
m|<a\s.*?/a>|isg
045743503/05/11 17:56ID:???
>>456
<a name="hoge"><a href="hoge">abc</a>

もうひといき
045845603/05/11 18:01ID:???
>>457
ハァ?<a> はネストしちゃいけないわけですが何か?
0459nobodyさん03/05/11 18:05ID:???
>>458
432> ニュースサイトからアンカータグの部分だけを取得してくる
だから、念には念を入れておくってことで。
046043503/05/11 18:07ID:???
一応IE6のパーサーで95点だから、その辺よろしく。
046145603/05/11 18:10ID:???
>>459
その「念」てなんだよ。点数出すからには採点基準を示せよな。
parse 対象となる HTML の DTD も示せ。BNF でも構わん。
それができないのならこんなの不毛なだけだ。
0462nobodyさん 03/05/11 18:14ID:???
じゃ、コレで如何だよ

my @list = $data =~ /<a(?:[^>]+)?>/g;
@uri = map{ $_=~ /href="?($http_regex)"?/; $1; } grep{/href="?($http_regex)"?/} @list;
046345903/05/11 18:17ID:???
>>461
ごめん、俺は435じゃない。
ネストしないんだからアレでイイと思うんだけど、
ニュースサイトがvalidなHTMLを書いていることは少ないから
「年」って行っただけぽ。
046443503/05/11 18:21ID:???
じゃあ、そろそろ80点以上の例でも示しておこう。

s/<!--.*-->//gs; # 前処理
@gets= $_=~ m!<A\s[^>]*?\bhref=.+?</A>!gsi;

どうだ、、、これで確実に「ゲッツ!」しろYO!
0465nobodyさん 03/05/11 18:25ID:???
>>464
URI以降も含むんでねーのかそれ・・・
046643503/05/11 18:29ID:???
>>465
  >>432嫁

s/<COMMENT>.*</COMMENT>//gs;
s/<!--.*-->//gs;
@gets= m!<A\s[^>]*?\bhref\s*=.+?</A>!gsi;

こんなのがもっと堅実かもな
046743503/05/11 18:30ID:???
間違った。。。iオプションがなくてはな

s/<COMMENT>.*</COMMENT>//gsi;
046843503/05/11 18:36ID:???
まだ間違ってるな

s!<COMMENT>.*</COMMENT>!!gsi;

まったくつくづくだな
046945603/05/11 18:44ID:???
適当にうやむやにごまかそうとしてんじゃねえよ。とっとと「採点基準」を示せよ。
0470あぼーんNGNG
あぼーん
047143503/05/11 18:51ID:???
>>469
だから、<a name="hoge"></a>
   とか
<!--<a href="hoge">--><a href="hoge">abc</a>

とかも考慮すると>>456は68点だな。

採点基準は漏れの直感だ
0472nobodyさん 03/05/11 18:54ID:???
ほれ・・・

s/<!--(?:(?!-->).)*-->//ig;
s/<COMMENT>(?:(?!<\/COMMENT>).)*<\/COMMENT>//gsi;
@gets = m/<a[^>]+href=[^>]*>(?:(?!<\/a>).)*<\/a>/gsi;
047343503/05/11 18:57ID:???
>>472
   できれば>>451を読んで欲しかった

正規表現は冗長になり過ぎると処理が遅くなりにけり
0474nobodyさん 03/05/11 18:58ID:???
なんや・・・
結局イチャモンつけたいだけか・・・
047543503/05/11 19:01ID:???
っていうか、普通に

<area href="url">ってタグあるの知ってる?
047645603/05/11 19:03ID:???
> 採点基準は漏れの直感だ

お前、どっか逝け。
0477nobodyさん 03/05/11 19:03ID:???
@gets = m/<a\s[^>]*href=[^>]*>(?:(?!<\/a>).)*<\/a>/gsi;

じゃ、これでいいんでは?
047843503/05/11 19:05ID:???
>>477
だいぶいい感じだな。できれば最短マッチのほうがシンプルで処理も速いが
047943503/05/11 19:08ID:???
>>476
それじゃ進歩しないぞ。ここは道場だからな。ビシビシいくぞ!
馴れ合いスレじゃないからな。

もちろん漏れが書いたのもまだ不完全なのかも知れん。つっこみどころが
あればつっこんでもっといいものを出せばいいんだ。
0480あぼーんNGNG
あぼーん
048145603/05/11 19:14ID:???
>>479
じゃあ意味の無い点数なんて付けるな。
第一、処理対象となる HTML がどんな仕様なのか前提があいまいで、
あとからコレはダメだアレはダメだなんてのは、
単にいちゃもん付けたいだけとしか思えん。
だったら最初から parse 対象 HTML を全て提示しとけ。
048243503/05/11 19:21ID:???
>>481
いちいち見ず知らずの漏れが付けた点数に反応してどうするよ。
おかしいと思えば無視しろよ。

HTMLの仕様は決まってるだろ。今まで書いたことがいちゃもんだといわれ
ても、漏れがやってるプログラミングの世界ではあらゆる状況を考慮しないと
とんでもないバグになってしまうから、まア職業病だと思ってくれ。
048345603/05/11 19:28ID:???
>>482
> HTMLの仕様は決まってるだろ。

だから漏れが <a> はネストしないって言ったら、 >>457 と言う。
だったらお前の脳内HTML仕様を提示しろと言ってるんだYO!
とんだ職業病だな。
048443503/05/11 19:33ID:???
>>483
確かに、HTML仕様としては>>457はダメだな。>>471を最初から書くべき
だな。ということで68点だな。
0485nobodyさん 03/05/11 19:45ID:???
>>472
だから、わざと冗長な正規表現をかいただけのはなしだが・・・
     ^^^^^^
手前ルールでやられりゃ、腹も立つやろうなぁ・・・
0486あぼーんNGNG
あぼーん
0487nobodyさん03/05/11 20:20ID:???
すげー!変な奴キター!
0488名無しさん@Meadow03/05/12 07:34ID:???
>>487
486みたいな香具師は2chでは普通ですが、何か。
0489nobodyさん03/05/12 07:49ID:???
>>488
>>435のことだよ
0490nobodyさん03/05/12 09:37ID:???
「詳説 正規表現」の第二版が今月下旬に出るみたいだね。
0491nobodyさん03/05/12 10:10ID:???
>>490 diffキボンヌ
0492nobodyさん03/05/12 10:28ID:85k2ng51
前処理でコメントタグ取るなら、
ここまでやるってのはどう?

/<(?:!(?:--[\s\S]*?--\s*)*(>)\s*|(?:script|style|SCRIPT|STYLE)[\s\S]*?<\/(?:script|style|SCRIPT|STYLE)>)/isg;
0493nobodyさん 03/05/12 10:47ID:???
>>492
iつけるんなら、
/<(?:!(?:--[\s\S]*?--\s*)*(>)\s*|(?:script|style)[\s\S]*?<\/(?:script|style)>)/isg;
これでいいんでない?

[\s\S] って .でいいんちゃうかな?
0494nobodyさん03/05/12 10:53ID:85k2ng51
>>493
そうだね、指摘サンクスコ(・∀・)
漏れのソース、i付いてなかった(;´Д`)
0495nobodyさん03/05/12 10:54ID:85k2ng51
とりあえず、コメント削除は、>>493の指摘で完成する物で、かなり逝けると思われ。
ありとあらゆるサイトのコメント入りHTML食わせてみたけど、
まず間違いなく削除してくれる。
100%ではないかもしれないけど。
0496あぼーんNGNG
あぼーん
0497nobodyさん03/05/12 22:56ID:???
サイトによってコメントの定義が違うからな(皮肉
0498nobodyさん03/05/19 22:15ID:pDSpAcPJ
ファイル名だけを変数に取り込む時にフルパスからファイル名だけを取り出す
正規表現はどう書けばいいのでしょうか。
たとえば下のフルパスからhttpd.confだけを取り出すような場合です。
C:\Program Files\Apache Group\Apache\conf\httpd.conf
0499あぼーんNGNG
あぼーん
0500nobodyさん03/05/19 22:36ID:???
>>498
\\([^\\+])$
(\ \以外 末尾)
0501あぼーんNGNG
あぼーん
0502nobodyさん03/05/19 22:58ID:???
>>500
perlなのですがエラーになりました。

-----test.pl------
my $path = $0;
$path =~ \\([^\\+])$;
print "\$path :\n";
print "$path\n";
----------------
0503nobodyさん03/05/19 23:17ID:???
>>502
あたりまえだろう

$path =~ /\\([^\\+])$/;
0504nobodyさん03/05/19 23:23ID:???
>>498

$a='C:\Program Files\Apache Group\Apache\conf\httpd.conf';
($_)=$a=~ /^.+\\(.+)$/;
print;
0505nobodyさん03/05/19 23:26ID:???
>>503
すいません。
改めて試しましたがファイル名test.pが取得できません。

-----test.pl------
my $path = $0;
print "$path\n";
$path =~ /\\([^\\+])$/;
print "\$path :\n";
print "$path\n";
----------------
050650003/05/19 23:33ID:???
すんません。typoです。
× \\([^\\+])$
○ \\([^\\]+)$

>>505
typoに関係なくそのスクリプトは間違っている。
もう一回本読め。
0507nobodyさん03/05/19 23:42ID:???
>>504
さっそく試してみました。
しかしフルパスが入ります。
環境は98です。

-----test.pl------
my $path = $0;
print "$path\n";
$path =~ /^.+\\(.+)$/;
print "\$path :\n";
print "$path\n";
----------------

>>506
ダメでした。
スクリプト自体が間違っていますか?
-----test.pl------
my $path = $0;
print "$path\n";
$path =~ /\\([^\\]+)$/;
print "\$path :\n";
print "$path\n";
----------------
050850403/05/19 23:45ID:???
>>507
資源の無駄だからもう書き込むな
スレが汚れる
0509nobodyさん03/05/19 23:48ID:???
>>508
すいません。
>>504の正規表現でhttpd.confが拾えました。
あとはスクリプトの間違いを修正してみます。
0510nobodyさん03/05/19 23:52ID:???
頭の固い香具師だな
0511nobodyさん03/05/20 00:17ID:???
>>509
>>>504の正規表現でhttpd.confが拾えました。
>>506の正規表現でも拾えてる。
0512nobodyさん03/05/20 00:33ID:???
>>511
500へのお礼を忘れてました。
確かに拾えます。
ですがまだ不具合があるので両方の正規表現を使って試している最中です。

-----test.pl------
my $path = $0;
print "$path\n";
($_)= $path =~ /\\([^\\]+)$/;
print "\$path1 :\n";
print "$_\n";

$a='C:\Program Files\Apache Group\Apache\conf\httpd.conf';
($_)=$a=~ /^.+\\(.+)$/;
print;
----------------
0513nobodyさん03/05/20 00:38ID:???
編集途中のソースが残っていたのでもう無視して下さい。
■ このスレッドは過去ログ倉庫に格納されています