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

正規表現道場@2ch Part2

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

リンクなどは>>2-5のあたりに。
0357nobodyさん03/04/11 11:44ID:???
>>356
今のところあまり使われてはいないものの、ほとんどどんな文字でもだね。
0358nobodyさん03/04/11 11:59ID:???
>>353
後半を
@[\w\-+\.]+\.[\w\-+\.]+
にするんじゃだめ?
0359nobodyさん03/04/11 13:09ID:???
実際にSMTPに繋いでみる。
0360nobodyさん03/04/11 19:44ID:???
実際に送信して、エラーが帰ってくるか試してみる。
0361nobodyさん03/04/15 07:50ID:???
>>356
空白と@を除く全ての1バイト文字とは違うの?
ドメインにより制限があるが、流動的になり得るので、
ドメイン別の場合分けは無意味と思う。
(1バイト文字=A-Z,a-z,0-9,キーボードから打てる記号)
0362はしのえみ好きー03/04/15 08:10ID:???
それを言うなら印字可能文字
0363nobodyさん03/04/15 12:10ID:GI84bLWk
先頭と最後にダブルコーテーションがない場合は
ダブルコーテーションで必ず囲みたい!

"aaa → "aaa"
aaa" → "aaa"
aaa → "aaa"
どうする?正規表現!
0364nobodyさん03/04/15 12:18ID:VH8m0AHo
s/^\"?([^\"]+)\"?$/\"(\1)\"/;
0365nobodyさん03/04/15 13:14ID:x65/25rD
>>364
ありがとうございます。
でも実行してみたら
"aaa → ""aaa
となってしまいました。。
0366nobodyさん03/04/15 13:20ID:???
>>365
まじで?
私は、余計なかっこがついてきたよ。
だから、こう書き直したら、直ったよ。

s/^\"?([^\"]+)\"?$/\"\1\"/;
0367nobodyさん03/04/15 14:26ID:fimoekOy
>>366
ありがとうございました。
直りました。
0368nobodyさん03/04/15 18:15ID:???
それだと"が途中に入ってる場合にうまくいかない。
それから、正規表現中の"は意味は無いからエスケープする必要は無い。

で、自分ならこう書く。

s/^"?(.*?)"?$/"$1"/
0369nobodyさん03/04/15 18:25ID:W26JC1si
「超」にマッチ、但し「超クール」の場合にはマッチしない、ていうのは
どうするんだろう・・・

超バッド←「超」にマッチ
超能力←「超」にマッチ
超クール←マッチしない

/超^(クール)/ じゃダメらしい・・・

unless(/超クール/){
 if /超/

以外でひとつ・・・
0370nobodyさん03/04/15 18:29ID:???
(?! ... )
037136903/04/15 18:32ID:???
>>379 即レスありがとう!

超(?!クール)

でマッチしますた。ていうか漏れの持ってる本に載ってないよ・・・捨てるか
0372nobodyさん03/04/15 18:54ID:???
5回以上の改行を一回の改行に置換したいのですが、上手くいきません。
\n{5,} マッチしませんでした
\n\n\n\n\n マッチしませんでした

どなたかお願いします・・・。
0373あぼーんNGNG
あぼーん
0374nobodyさん03/04/15 19:08ID:???
>>372
s/\n{5,}/\n/gs ←この最後のsはつけました?
0375nobodyさん03/04/15 19:14ID:???
改行コードが統一されていないとか。
0376nobodyさん03/04/15 19:41ID:???
Perlの拡張じゃなかった?

(?! ) (?= ) とか。そういうのは断り書きしたほうが委員でないか
0377nobodyさん03/04/15 20:09ID:???
ツールによって文法も使える表現の範囲も違うから
何を使ってやりたいのかをちゃんと書いたほうがいいと思う
0378nobodyさん03/04/15 20:58ID:???
>>377
何を使って: bregexp.dll使用のテキストエディタ
やりたいこと: 5回以上の改行は1回にする

です。
0379nobodyさん03/04/15 23:21ID:qSlvjoha
小さなパーサを作っていて,不等式を解析したい。左辺と右辺はそれぞれ一単語または""にはさまれた一以上の単語というルールがある。
で,具体的には不等式の左辺と右辺を取り出したい。

たとえば,
$statement = q["abc de" > 123 or abcde = "zz zz"];
だと,"abc de"とabcdeが左辺,123と"zz zz"が右辺。

これを解析するために

$operand = '(?:<=|>=|>|<|=)';
$var = '(?:\w+|"[^"]*")';
$statement =~ s/($var)\s*$operand\s*($var)/(left) $1 (right) $2/g;
print $statement;

とかすると

(left) "abc de" (right) 123 or (left) abcde (right) "zz zz"

という出力が得られる。

さて,
0380nobodyさん03/04/15 23:22ID:qSlvjoha
問題は左右辺を''でくくる場合も許した場合。たとえば,

$statement = q["abc de" > 123 or abcde = 'zz zz'];

の場合に

(left) "abc de" (right) 123 or (left) abcde (right) 'zz zz'

としたい。

$operand = '(?:<=|>=|>|<|=)';
$var = q!(?:\w+|("|')[^\1]*\1)!; #ここを変えた
$statement = q["abc de" >123 or abcde = 'zz zz'];
$statement =~ s/($var)\s*$operand\s*($var)/(left) $1 (right) $2/g;
print $statement;

だとまったく解析が成功しない。どうして?

0381nobodyさん03/04/15 23:27ID:???
あの、、長文テキストを指定桁数で改行する正規表現をどうやって書けばよいでしょうか。。
本を読んで2日目です、、、急に必要になってしまいました。おやさしいかた、おしえてください。よろしくおねがいいたします。
0382nobodyさん03/04/15 23:35ID:qSlvjoha
>>381
http://www.din.or.jp/~ohzaki/perl.htm#JP_Fold
0383nobodyさん03/04/15 23:37ID:???
>>380
$statement =~ s{
 (\w+|"[^"]+"|'[^']+')
 \s*
 (?:[<>]=?|=)
 \s*
 (\w+|"[^"]+"|'[^']+')
}
{(left) $1 (right) $2}gx;
0384nobodyさん03/04/16 00:18ID:???
>>382
どうもです。
0385nobodyさん03/04/16 13:17ID:QKerHoGZ
HTMLのコメントタグを拾う書式ってどんなのがありますかね?
たしかPerlメモで拾った
<!(?:--[^-]*-(?:[^-]+-)*?-(?:[^>-]*(?:-[^>-]+)*?)??)*(?:>|$(?!\n)|--.*$)
では、マッチしないケースがあるみたいです。
(ここのHTMLなど:http://messages.yahoo.co.jp/yahoo/Computers___Internet/Hardware/Mobile_Phones_/index.html)

<!(?:--(?:(?!--).)*--\s*)*>
だと大丈夫なんですが、十分なんでしょうか?
他にコメントタグの記述形式があれば知りたいです。
0386nobodyさん03/04/17 11:44ID:326c+Ekv
質問です。
ある文字列内に、所定の単語が含まれていない 場合を判定する正規表現を書きたいです。どういう書き方が良いですか。
[^abc] ですと、a,b,cのいずれかが含まれていない、という判定になってしまいます。そうでなく、abc という文字列が含まれていない、というのを判定したいです。
0387nobodyさん03/04/17 13:12ID:???
>>386
!~ /abc/g;
ではあきまへん?
0388nobodyさん03/04/17 13:14ID:???
>>386
処理系にもよるが、/abc/ の結果を反転したほうが簡単だと思う。
0389nobodyさん 03/04/17 13:17ID:???
(?:(?!abc).)*
とか

perl,rubyあたりでしかつかえんよーな・・・

0390nobodyさん03/04/19 15:42ID:???
htmlのタグが混じっている文書から、ある特定のURLだけを抜き出したいのですが
どのようにすればいいのでしょうか?

例えば<td>などで挟まれているhttp://www*.hoge.ne.jp/*****(*は任意の数字)だけを
抽出したいのです
0391nobodyさん03/04/19 16:06ID:9ZhNrFm8
げっ・・・age忘れてた
0392はしのえみ好きー03/04/19 17:08ID:???
><td>などで挟まれているhttp://www*.hoge.ne.jp/*****(*は任意の数字)だけを抽出
/<[^>]+>http://www\d+.hoge.ne.jp/\d+</[^>]+>/
?
0393はしのえみ好きー03/04/19 17:08ID:???
げ。デリミタは/じゃだめだな。!とかにして。
0394はしのえみ好きー03/04/19 17:11ID:???
あ、Perlスレじゃなかったね。(だから.+?使わなかったのに・・・鬱)
しかもピリオドエスケープしてなかったし(もうだめぽ(´・ω・`)
<[^>]+>http://www\d+\.hoge\.ne\.jp/\d+</[^>]+>
0395nobodyさん03/04/19 20:00ID:???
<td[^>]*?>http://www\d\.hoge\.ne\.jp/\d+</td>
039638603/04/19 23:46ID:???
色々アドバイスありが�d。!abcでいけました。たぶん。。JDK1.4.1のregexです。
0397山崎渉03/04/20 05:59ID:???
   ∧_∧
  (  ^^ )< ぬるぽ(^^)
0398nobodyさん03/04/24 17:15ID:/44ojQ66
<script language=hoge>〜</script>
の範囲を削除したいのですが、こんなんでいいんでしょうか。

s/<script[\s.\S]\s*(.*)\s*>[\s.\S]*<\s*\/script>//gi
039939803/04/24 18:29ID:/44ojQ66
その後あれこれ考慮して、

s/<script\s*.+?>.+?\s*<\/script>//gi

これに落ち着いた感じなんですが、どうでしょうか?
0400nobodyさん03/04/24 18:32ID:???
s#<script[^>]*>.*?</script>##gi
0401nobodyさん03/04/24 18:33ID:???
s#<script[^>]*>.*?</script>##igs
か。。
0402nobodyさん 03/04/24 18:36ID:???
>>399
s/<script[^>]*>(?:(?!<\/script).)*)<\/script>//gi

とか・・・
0403nobodyさん03/04/24 23:39ID:???
s#<script.*?>.*?</script>##isg
0404nobodyさん03/04/24 23:40ID:???
s#<script.*?>.*?</script>##isg
040539903/04/25 01:34ID:fbvwVtSF
短くなるもんですね。。。
>>399の記述でも、目的は達しているように見えるのですが、
ご教示頂いたものを試してみようと思います。

現在、コメントタグの削除に取り組んでいますが、
s/<!--[^>]*-->//g
これで、一応目的は達しているように見えます。
複数行またがるコメントタグも削除できているようです。
しかし、より効果的な記述方法はあるでしょうか?
0406nobodyさん 03/04/25 04:34ID:???
>>405
コメントタグは < >が含まれることがある(というかブラウザー的にはエラーにならない)
のでそれじゃ駄目
あと、改行も問題有るので

s/<!--(?:(?!-->).)*)-->//gs

ぐらいにしとかにゃだめなんじゃない
0407nobodyさん03/04/25 05:04ID:???
>>405
http://www.din.or.jp/~ohzaki/perl.htm#HTML_Tag
040840503/04/25 10:00ID:EpsK+/d8
>>406
クスコです。試してみます。

>>407
情報源、クスコです。
Perlメモは読んでまして、そこのコメントタグも試しました。
ただ、あれでは意図しない部分まで削除してしまうケースがあるようです。
040912303/04/25 10:36ID:HCZY3VXf
javaの場合
※jdk1.3は正規表現はつかえないから別のライブラリを使う(以下参照)
※jdk1.4は標準でついていたのでそれを使う(使い方忘れた、自分で探せ)
String aaa = \"123456789\";
Pattern pattern_1 = compiler.compile("456",Perl5Compiler.CASE_INSENSITIVE_MASK);
aaa = Util.substitute(matcher,pattern_1,000,aaa,Util.SUBSTITUTE_ALL);
041040503/04/25 12:08ID:EpsK+/d8
海外サイトなんだけど、javascript.faqtsに、コメントタグを削除する、いい答えがありました。
SCRIPTタグの削除も含んでます。
http://www.faqts.com/knowledge_base/view.phtml/aid/21761/fid/597
これの下の方。

/<(?:!(?:--[\s\S]*?--\s*)*(>)\s*|(?:script|style|SCRIPT|STYLE)[\s\S]*?<\/(?:script|style|SCRIPT|STYLE)>)/g;

これ使ったら、見事にうまくいったヨカン。
0411あぼーんNGNG
あぼーん
0412あぼーんNGNG
あぼーん
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
■ このスレッドは過去ログ倉庫に格納されています