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

正規表現道場@2ch Part2

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

リンクなどは>>2-5のあたりに。
0313nobodyさん03/03/29 11:26ID:???
$str = q|kふぉあsdん@ごあsdんg@おあんう゛ぁ@おsなおさkんが@おsんdg@お|;
if ( $str =~/(.+)\1/ ) {
    print 'OK';
} else {
    print 'NG';
}
0314nobodyさん03/03/29 17:46ID:???
Perlメモのやつを使えば、全角文字も1文字として扱える
0315nobodyさん03/03/29 18:25ID:???
半角しか考えないバージョンの答えはこれ。多分
/(.+)\1{N,}/

Nはn - 1で。
031630903/03/29 22:08ID:xi1Z4LcN
できないかな。。。
一応サンプル
ttp://thebbs.jp/common/thetop/index.html
連続した文字に反応します。
このようにしたいんですけど。。。
0317nobodyさん03/03/29 22:17ID:???
>>316
>>313-315を読んだか?
031830903/03/31 00:38ID:rrn9gB8/
お〜!!
すいません、>>315サソのでいけました!
みなさんどうもありがとう・゚・(ノД`)・゚・
031930903/03/31 00:50ID:???
あ、でも半角だけか。。。(´・ω・`)
0320nobodyさん03/03/31 05:06ID:???
>>319
ま、当面は大丈夫じゃないの?
0321nobodyさん03/03/31 18:43ID:???
Perlメモから、文字の正規表現を持ってくればできる。EUC-JPのみ対応

$ascii = '[\x00-\x7F]';
$twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]';
$threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';

/((?:$ascii|$twoBytes|$threeBytes)+)\1{N,}/
0322nobodyさん03/03/31 18:46ID:???
あ、でも>>315でも2バイトの繰り返しとして判断されるから、
ちゃんと動く(ように見える)かも。ずれた時は…
0323Perl03/04/04 15:20ID:???
? (十進数) {2,4} ;
?x (十六進数) {,4} ;
でない #(任意の16文字) にマッチさせるにはどうしたらよいですか。
0324名無しさん@Meadow03/04/04 23:02ID:???
>>323
わけわか
人にわかるように書け

0325nobodyさん03/04/04 23:23ID:???
>>323
同じくわけわか
任意の16文字にマッチさせたくないものを書いて
0326nobodyさん?03/04/05 04:37ID:bmLMbrZJ
$str = '123 名前:<font color="#008800"><b> nobodyさん </b></font>' から
<b></b>タグで挟まれた文字列(レスの名前部分)だけ残す場合、どんな方法がありますか?

$str =~ /<b>([^<]+)<\/b>/; $str = $1;
$str =~ s/.*<b>([^<]+)<\/b>.*/$1/;
ってのはエレガントじゃないですよね
0327nobodyさん03/04/05 04:47ID:???
($str) = $str =~ /<b>([^<]+)<\/b>/;

これじゃだめ?
0328nobodyさん?03/04/05 05:08ID:???
>>327
配列コンテキストだとマッチした文字列の配列をを返すんですね。
なるほどサンクスです。
0329Perl03/04/05 10:25ID:???
>>323の?は、半角の&です、、、
化けてしまった。
0330Perl03/04/05 10:26ID:???
半角の&#だった、スマソ。? &#
0331デフォルトの名無しさん03/04/05 11:11ID:E+nPGg0Q
>>330
わけのわかるように書け、といてるのがわからんかな。
(a) /#.{16}/ # '#'に続く任意の16文字じゃ
(b) /?[0-9]{2,4}/ # '?'に続く十進数2個〜4個じゃ
(c) /?(x[0-9a-z][0-9a-z]){,4}/ # '?'に続く十六進数表記0個〜4個じゃ
(a)は、(b)でも(c)でもないから、(a)がおぬしの求める解そのもの
ではないのかの。
(b)も(c)も含まぬ(a)をマッチさせたいのではないのかの。
それなら別の問い方がある。日本語をべんきょし直してこい
0332nobodyさん03/04/05 14:40ID:7kbMg08s
\nああああ 2003/6/08\n\nsdfg 2004/9/9\n\nぉいこいjk\n

から最後の\n〜\nを消したいのですがどうすればいいですか?
結果的に
\nああああ 2003/6/08\n\nsdfg 2004/9/9\n
というふうにしたいのですが
0333nobodyさん03/04/05 14:47ID:???
$ perl -e '$_="\nああああ 2003/6/08\n\nsdfg 2004/9/9\n\nぉいこいjk\n";s/\n[^\n]+\n$//;print'
0334nobodyさん03/04/05 16:15ID:???
>>332
join('\n',(split(/\n/,"\nああああ 2003/6/08\n\nsdfg 2004/9/9\n\nぉいこいjk\n"))[0..3])

こじつけ(w
033533203/04/05 17:02ID:7kbMg08s
すいません\nは改行ではなく文字として扱いたいのですが
0336nobodyさん03/04/05 17:10ID:???
>>335
はあ?\\nでいいだろ?入門書買え
0337Perl03/04/05 22:53ID:???
>>331
> (b)も(c)も含まぬ(a)をマッチさせたい
そうです。
質問者の癖に揚げ足を取っとくと、
(C)は [0-9a-fA-F]。

「純粋な正規表現」ではできないのですか?
Perlなら下記でいけそうですが。
/(?<!&)#.{16}/

?(数字); にはマッチしなくて
?(文字); や?(;以外の任意)にはマッチ なんてできませんよね?
0338nobodyさん03/04/05 23:36ID:???
マッチさせてから考える、っということにしよう。
0339nobodyさん03/04/06 00:32ID:???
言ってることがわけわかだから終了でいいだろ
0340Perl03/04/06 01:01ID:???
この板って、&がかけないのか?
同じpc2鯖でもweb製作は使えるのに。

テスト & &です。
&amp; &です。
&# ?です。
0341nobodyさん03/04/09 16:59ID:???
メールのログからメールアドレスだけ除いて出力したいんですが、
どういう正規表現使ったらいいでしょうか
http://www.din.or.jp/~ohzaki/perl.htm#Mail
を見てみたのですが、ちょっと分かりませんでした…。
言語はまだ未定なのですが、perlでできればいいなと考えてます。
0342nobodyさん03/04/09 17:12ID:???
どんなログ形式になってるのか知らないけど、ログの1行を空白で分割すると、
決まった場所にメールアドレスが来てない?
0343nobodyさん03/04/09 17:21ID:???
>>341
ログのフォーマットぐらい書けよ。
その内容によっては正規表現じゃなくたってできることあるし。
0344nobodyさん03/04/09 17:33ID:???
>>342,325
そうですね。
OEのメッセージをテキストで保存したものですが、
----↓一行目から----
送信者: <[email protected]>
宛先: <[email protected]>
件名 : テスト
日時 : 2003年4月9日 17:33
--------------------

てな感じになってます。
ヘッダ部分は決まった場所なんですが、
本文中のメアドも消したいんです。
0345nobodyさん03/04/09 18:09ID:???
>>344 Monazilla関係とみた
0346nobodyさん03/04/10 01:00ID:+Bf7VwF4
どのくらい厳密にメールアドレスを考えるか、って問題?
0347nobodyさん03/04/10 01:08ID:???
メアド部分を探し出し空白に変換すればいいわけですね。
0348nobodyさん03/04/10 01:58ID:???
>>344
メールアドレスの正規表現はググればいくらでも見つかるでしょ
どっちみち、perl5.6以前は完全には表せないけどあまり支障はないと思う
0349nobodyさん03/04/10 03:20ID:vlrWfcuj
あまり知障はないと思う
0350あぼーんNGNG
あぼーん
0351あぼーんNGNG
あぼーん
0352あぼーんNGNG
あぼーん
0353nobodyさん03/04/11 04:03ID:???
341の母でございます。(・・・ってパターンは古すぎだな)
もまいらオススメのMail Addressの正当性チェックパターンを是非341に押しえて
ください。
教科書的には
/^[\w\-+\.]+\@[\w\-+\.]+$/i
・・・って事になるかもしれないけど、これだとage@sageでも通ってしまいまふ。
http://www.din.or.jp/~ohzaki/perl.htm#Mailは現実的じゃないし、perl上で@で
splitして要素数数えてから左辺右辺を個別に評価した方が確実なんでしょうけど、
ここは正規表現一発って事でおながいします。
0354nobodyさん03/04/11 04:18ID:???
/@/
0355nobodyさん 03/04/11 04:31ID:???
>>353
現実的ってのがよーく解らんので答えようがないんじゃけど
0356nobodyさん03/04/11 06:29ID:???
まず、@より左に使える文字の一覧希望。
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]+/

メアドの正規表現ってこんな感じでいいの(初心者でつ)?
■ このスレッドは過去ログ倉庫に格納されています