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

正規表現道場@2ch Part2

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

リンクなどは>>2-5のあたりに。
0266nobodyさん03/03/11 11:12ID:???
>>265
良かったな。
0267名無しさん@Meadow03/03/11 11:16ID:wliWOweu
>>263
Perlだしゅ。正規表現じゃないな。
while(<>) {
@zero=m/0/g;
@ichi=m/1/g;
if ($#zero % 2 != 0 and $#ichi % 2 == 0) {
print;
}
}
0268nobodyさん03/03/11 11:17ID:???
>>263
その問題文、「次の言語に」って言い回しからしてなんか怪しくない?
0269nobodyさん03/03/11 11:45ID:???
>>268
どういうこと?原文ままだと

*3.7 次の言語に対する正規表現を書きなさい.
 a) 5個の母音a,e,i,o,uがこの順序でどこかに現れる英字列すべて
 b) 辞書式順序の関係に従って現れる英字列すべて
 (略)
 f) 0と1からなる列で,0は偶数回,1は奇数回,現れるものすべて
 (以下続く)

「コンパイラI 原理・技法・ツール」(通称ドラゴンブック)ていうやつの練習問題。
0270nobodyさん03/03/11 14:35ID:???
>>269
ソレ、学校の課題かなんかじゃねえの?
それなら自分でやれよ。

もし違うならスマソ
0271nobodyさん03/03/11 15:29ID:???
>>269
普通なら「次の文字列に対する〜」だと思うが。
言語?
0272nobodyさん03/03/11 16:10ID:???
ところで。
オライリージャパンの「正規表現」って本読んだ。
ちょっと古めなのであれだったけど。
(\4000)

書いてある内容はあれだったけど、
説明のしかたがクソだった。

よくオライリーからあんなクソ説明本が出たもんだ。
読んでる途中で嫌になってくる。
0273nobodyさん03/03/11 18:14ID:???
>>272
アンタの説明も(ry
0274nobodyさん03/03/11 19:10ID:???
>>270
いや、ただ気になったので。この類の本って問題だけで答えがないってのが
多い気がする。

>>271
「言語」はあるアルファベット(文字集合)からなるものの列をいうっていうようなことが
書いてあるので、たぶんここでは文字列っていうのと同じとみていいと思う。
「言語 受理」で検索するとそれっぽいページが多くヒットするので分野によっては
普通の表現なのかも(「受理」はまぁつまり「マッチが成功する」って言う意味)。
0275nobodyさん03/03/11 23:48ID:???
あぁー分からないよぉ。。もちろんPerlの拡張正規表現は使わないんでしょ?
0276nobodyさん03/03/12 00:09ID:???
>>275
あんたが何がわからないかわからないのだが
0277nobodyさん03/03/12 00:23ID:???
>>275
使えばできる?
0278nobodyさん03/03/12 22:04ID:hmpHRxfR
2ちゃんのスレッドのソースから名前だけ取り出す正規表現ってどうすればいいですか?
0279nobodyさん03/03/12 22:31ID:wNWBQmqk
>>272
たぶんあなたのレベルの問題だと思うぞ。
あと2,3回我慢して読んでみなよ。
0280nobodyさん03/03/12 22:38ID:???
.*
と
.+?
の違いって何ですか??
0281あぼーんNGNG
あぼーん
0282nobodyさん03/03/13 02:18ID:???
>>280
前者にヒットして後者にヒットしないものは空文字列くらいかな。
0283nobodyさん03/03/13 02:21ID:???
>>282
後者にはなんでヒットしないの?
0284nobodyさん03/03/13 02:42ID:???
>>283
そういうルールだから
0285nobodyさん03/03/13 15:28ID:???
あれ、
(x?) って (|x) の略記法だと思ったんだけど。
だから空にもマッチするんじゃないの?
0286nobodyさん03/03/13 15:44ID:???
>>285
その"?"と、>>280の"?"では意味が違います。
>>280の"?"は量指定子(この場合は"+")の後ろにありますので、
これは「最短のマッチを選べ」という指示になります。
結果として、".+?"は「何か一文字」にマッチするということになりますね。
0287山崎渉03/03/13 16:58ID:???
(^^)
0288nobodyさん03/03/13 19:43ID:???
>>286
なるほど、"+?" で一つのメタ記号なんですね。ゴミレススマソ
0289nobodyさん03/03/13 19:45ID:???
>>288
違うぞ。
0290nobodyさん03/03/14 00:04ID:???
0291nobodyさん03/03/14 00:04ID:???
0292nobodyさん03/03/14 00:04ID:???
0293nobodyさん03/03/14 00:05ID:s293/lDl
293get
0294nobodyさん03/03/14 00:23ID:???
{0,1}という意味での?と、
* +の後ろにくっつけた?は意味が違う。

だから、*? +?で1つのメタ文字として考える方が正しいといえる。
0295nobodyさん03/03/14 00:38ID:???
>>294
*?とか+?は、メタキャラクタのみで構成されているってだけの話で、
所詮は正規表現の1パターンでしかないと思ふ。
0296nobodyさん03/03/14 18:50ID:???
>>282は間違いなんですね?
0297nobodyさん03/03/14 20:20ID:???
>>296
伺う前に自分で実験しる。これ基本。
0298nobodyさん03/03/14 21:01ID:???
>>297
わかりやしたです。
0299nobodyさん03/03/15 23:25ID:???
量指定子の後ろに「?」をつけると「最短一致」
だから>>280は間違いと。やっとわかったよ。
0300nobodyさん03/03/20 21:24ID:8BKMA1mq
>>299
ちがうよ(ぷ
0301nobodyさん03/03/21 01:13ID:???
>>263 http://www.din.or.jp/~ohzaki/regex.htm#AevenBodd
0302nobodyさん03/03/26 17:02ID:4WzRK9Se
文字列の中で、「;」を消したいんだけど「<」や「>」の「;」は
そのままにしておきたいような場合はどのように表記すればいいんでしょうか?
s{[^(?:&|<|>|")];}{}g とか
s{[^&|<|>|"];}{}g とかやってみましたがうまくいかず。
どなたか助けてください。
030330203/03/26 17:16ID:4WzRK9Se
↑間違えました。

文字列の中で、「;」を消したいんだけど「&lt;」や「&gt;」の「;」は
そのままにしておきたいような場合はどのように表記すればいいんでしょうか?
s{[^(?:&amp|&lt|&gt|&quot)];}{}g とか
s{[^&amp|&lt|&gt|&quot];}{}g とかやってみましたがうまくいかず。
どなたか助けてください。
0304nobodyさん03/03/26 19:37ID:???
>>303 Perlならこれでどうだ
s/(&(amp|lt|gt);)|;/$1/g
0305nobodyさん03/03/26 19:42ID:???
s/(?<=&\w+);//g
0306nobodyさん03/03/27 01:45ID:lpoVliEY
はじめまして。正規表現覚えたての者です。
if($FORM{'pass'} =~ /[0-9]pass/)

わかると思いますが、これは$FORM{'pass'}が[0-9]passだったら○○する、という命令なんですけど、
この0から9を0から24にしたいんです。
if($FORM{'pass'} =~ /[0-24]pass/)
これじゃあ0から2と認識されてしまいました。

どうかご教授お願いします。。
0307nobodyさん03/03/27 02:14ID:DK9B1aQJ
>>306
if($FORM{'pass'} =~ /(1?[0-9]|2[0-4])pass/)
でいいんじゃないかなあ。
0308nobodyさん03/03/27 02:20ID:DK9B1aQJ
>>306
if($FORM{'pass'} =~ /(\d+)pass/ && $1<24)
とかでもできるかなあ。
0309nobodyさん03/03/28 10:31ID:q5wWnzii
なんらかの文字列がn回以上続く という書き方はどうすればいいのでしょう?
/.{10,}/
こう書いたのですがなんでも10回続けばマッチしてしまう(10文字以上の長さだったらマッチ)
kふぉあsdん@ごあsdんg@おあんう゛ぁ@おsなおさkんが@おsんdg@お
にマッチせず、
あいうえお!!!!!!!!!!!!!!!!
や、
あいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえお
などにマッチさせたいんですが、どういう書き方をすればいいのでしょうか?

どうぞ、よろしくお願いします。
0310nobodyさん 03/03/28 10:45ID:???
>>309意味不明
kふぉあsdん@ごあsdんg@おあんう゛ぁ@おsなおさkんが@おsんdg@お

コレだって10文字以上だろ
人間にとって意味がある文章を洗い出すって意味なら無理
0311nobodyさん03/03/28 11:26ID:???
>>309
/(.+)$1{9,}/ じゃダメ?。あんましオススメしないけど。
031230903/03/29 03:39ID:WGdDwe6j
すいません、言葉が足りなかったようですね。。。
なんらかの文字列がn回以上続く
↓
なんらかの文字列が連続でn回以上続く

「連続」で続いてないとだめなんです。
だから、
kふぉあsdん@ごあsdんg@おあんう゛ぁ@おsなおさkんが@おsんdg@お
は、マッチしません。
あいうえお!!!!!!!!!!!!!!!!
は、「!」が10個以上あるのでマッチします。
あいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえお
は、「あいうえお」が10個以上あるのでマッチします。

こんな表現は無理なんでしょうか?

>>311
これでは無かったです。
単にn文字以上、ではなく、連続で続くとマッチさせたいんです。
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\"/;
■ このスレッドは過去ログ倉庫に格納されています