トップページphp
986コメント301KB

正規表現道場@2ch

■ このスレッドは過去ログ倉庫に格納されています
0001ヽ(´▽`)ノ2001/07/26(木) 09:03ID:???
以外と毛嫌いして居る人も多そうな正規表現、
でもperlを使いのなす上で避けて通れない道だったりするかもです。
そこで、スクラップブック的に目に止まったカッコイイ正規表現を
書き留めておこうと言うスレッドです。
質問する時は言語と、得たい結果をなるべく詳しく書いてね。

取り合えず僕が知ってる有用なリンクです。
http://www.din.or.jp/~ohzaki/perl.htm
http://www.kt.rim.or.jp/~kbk/regex/regex.html

もっとイイ(・∀・) リンクは>>2-10さん辺りが書いてくれるカモ・・・・
0624nobodyさん02/09/22 08:53ID:GGE38Iwz
>>623
そうかー、さんきゅー助かった!
迷惑ついでにもうひとつ聞くけど、
substr使うより、正規表現使ったほうが処理早い?

「何文字かの文字列を先頭の2文字だけに変換する」
という処理を数千件行うんだけど、どっちが早い?
数千件程度じゃあんまり変わらんかw
0625名無しさん@Meadow02/09/22 09:03ID:t+76B0UP
>>624
死らん。やってみて報告キボンヌ。
$start=time();
while(<>) {
s/(^..).*/$1/; #または、substr($_, 0, 2);
}
$end=time();
print $end-$start, "\n";

0626nobodyさん02/09/22 09:11ID:GGE38Iwz
>>625
数千件と言いながら3357件しかないので、
たいして変わんなかったw
期待はずれスマソ

0627名無しさん@Meadow02/09/22 09:12ID:t+76B0UP
>>642って書いたけど、その後の処理の内容が問題じゃん。
s///は$_が変化している。substrはそのまま。
$_にさらに処理を加えるなら、s///にしなきゃだめだけど
最初の2文字出すだけならprint substr...の方が早いっしょ。
0628nobodyさん02/09/22 09:20ID:GGE38Iwz
>>627
そかそか、勉強になった、さんくすコ
0629nobodyさん02/09/22 19:02ID:???
正規表現は基本的に遅いよ。
他のやり方でやろうとすると数行並べなきゃならなくなるような
処理なら素直に正規表現使った方が速くなることもあるけど。

use Benchmark;
timethese(500000,{
1=>q{
$hoge = '123456789';
$hoge =~ s/^(..).*/$1/;
},
2=>q{
$hoge = '123456789';
$hoge = substr($hoge,0,2);
}
});
Benchmark: timing 500000 iterations of 1, 2...
1: 20 wallclock secs (20.69 usr + 0.00 sys = 20.69 CPU) @ 24167.43/s (n=500000)
2: 3 wallclock secs ( 3.55 usr + 0.00 sys = 3.55 CPU) @ 141003.95/s (n=500000)
0630名無しさん@Meadow02/09/23 10:25ID:???
>>629
べんきょになりましたm(__)m
0631nobodyさん02/09/23 14:48ID:???
JRE32v1.17で

std::string
string
std::vector
vector

にヒットする正規表現がわかりません・・・

(std::)?string|vector

だと、std::が付いてないヤツにヒットしないです
0632nobodyさん02/09/23 14:50ID:???
(std::|)?string|vector













063363102/09/23 14:54ID:???
>632
そ・・・そんな単純な事なのか・・・
ありがとうございました
0634名無しさん@お腹いっぱい。02/09/24 23:42ID:???

きっと誰かやってると思うんだけど、日本語を含む文字列中の , . など
区切り文字を空白に置換する正規表現を教えてください。
できれば、。「 」なんかもできるといいです。
0635nobodyさん02/09/24 23:58ID:???
>>634
tr/,./ /;
s/\x81[\x40-\x42]/ /g;#SJIS
0636nobodyさん02/09/25 00:03ID:???
s/\x81[\x40-\x42]|[^\x81-\x9f][,.]/ /g;#SJIS
0637nobodyさん02/09/25 00:11ID:???
>>636
( ´,_ゝ`) プッ
063863602/09/25 00:13ID:???
あ、いろんな意味でダメだこれ。
0639名無しさん@お腹いっぱい。02/09/25 00:16ID:???

>635-636
すみません。EUC-JPなんです。
とりあえず、JIS X 208の01-03区は記号っぽいので、
tr/,./ /;
s/[\xA1-\xA3][\xA1-\xFE]/ /g;
とやってみましたが日本語が化ける場合があります。
064063702/09/25 00:25ID:???
では、わたしから

s/[.,]|\xa1[\xa2\xa3\xd6\xd7]/ /g;
0641nobodyさん02/09/25 00:42ID:???
>>640
「◆□」とかの\xa2\xa1\xa2\xa2みたいに並んだ文字で誤変換するぞ
0642nobodyさん02/09/25 00:47ID:???
区の指定と点の指定を区別せにゃならんな。
064363702/09/25 00:58ID:???
そこまで完璧に処理するとなるとオーバーヘッドがでかくなるんでないかな
一応以下のやつではどうだ?(16進と8進がいりまじってるけどきにするな)

s/([.,]|\xa1[\xa2\xa3\xd6\xd7])|(\216[\241-\337]|\217?[\241-\376].|.|\n)/$1?' ':$2/ge;
0644nobodyさん02/09/25 01:05ID:???
この辺嫁。
http://www.din.or.jp/~ohzaki/perl.htm#JP_Match
0645名無しさん@お腹いっぱい。02/09/25 01:50ID:???

>>640-644
レスありがとうございます。
>>644のリンク先に書いてある方法で、
s/\G((?:$ascii|$twoBytes|$threeBytes)*?)(?:[\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]|[\xA1-\xA3][\xA1-\xFE])/$1 /g;
でうまくいきそうです。
0646nobodyさん02/09/29 19:27ID:knautRXm
URLに使える文字がエスケープされていたら(%7Eとか%2Eとか)
元に戻す( ~ とか . とかに)という処理を正規表現で行えますか?
0647nobodyさん02/09/29 19:35ID:???
(゚д゚)ハァ?
URLデコードで検索しろや。
0648nobodyさん02/09/29 20:32ID:knautRXm
URLデコードだとデコードしたら意味が変わる文字までデコードしちゃうじゃないですか。
安全にデコードできるパターンだけを元に戻したいんですけどそういう判定を
正規表現でできますか? という質問。
0649nobodyたん02/09/29 21:46ID:???
>>648
できる。
0650nobodyさん02/09/30 09:51ID:???
>>648
ふつーは単純にURLでコードすりゃいいだろ。
何か特殊な事情があるならやりたいことを詳しく書け!
0651nobodyさん02/09/30 12:56ID:???
>>648
指定が面倒そうだから一度エンコードしてデコードし直せば?
s/%([a-f\d]{2})/pack("H2",$1)/ieg;
s|([^\w/\.&%?~+=:@#\-])|'%'.unpack("H2",$1)|eg;
065265102/09/30 12:58ID:???
違う、デコードしてエンコードし直す、だな。
0653nobodyさん02/10/01 01:46ID:m9+B5ZAC
>>650
URLを同一性チェックのために正規化したいんです。
>>651
それだと最初はエンコードされてなかった / とか # とかも
エンコードされてしまいまつ…
0654nobodyさん02/10/01 01:57ID:???
>>653
意味わかって言ってる?
>>651のは「\w/.&%?~+=:@#-」以外の文字をエンコードするって
意味だぞ。
0655nobodyさん02/10/01 10:50ID:???
>>654
ごめん '[' とか ']' とかが、とでも読み替えてください
0656nobodyさん02/10/01 10:56ID:???
ていうか最初は %2F にエンコードされてた / が
デコードされてしまうのでやっぱり困ります。
同一視されては困るからエンコードしてるのに
区別がつかなくなっちゃう。
0657nobodyさん02/10/01 12:21ID:???
>>656
だから意味考えろって。
'[' ']'をエンコードさせたくないなら[^〜]の中に
\[\]を加えればいいだけだろ。
/はエンコードしたいなら[^〜]の中の/を外せばいいだろ。
お前の頭にゃ何が詰まってんだ?
エンコードしたくないものを[^〜]の中に並べるだけ。
>>651のはただの一例だろ。実際に何を並べるかくらい自分で考えろ。
0658nobodyさん02/10/01 12:31ID:???
>>656
同一視って、何と何が?
0659nobodyさん02/10/01 12:35ID:???
>>656まずは例を出してみようよ。この文字列を
このようにしたい、って感じで。

君の説明わかんないよ。
0660nobodyさん02/10/01 12:48ID:???
>URLに使える文字がエスケープされていたら(%7Eとか%2Eとか)
>元に戻す( ~ とか . とかに)という処理を正規表現で行えますか?

>ていうか最初は %2F にエンコードされてた / が
>デコードされてしまうのでやっぱり困ります。

このへんが特にわからないね。
URLで使える文字を戻したいんじゃ無かったのか?
0661nobodyさん02/10/01 12:59ID:???
質問しとる方も何がしたいのかわかってないんちゃうか?
0662nobodyさん02/10/01 15:00ID:???
>>657-660
最初が「/%2F」なら「//」でも「%2F%2F」でもなくて
「/%2F」のままなるようにしたいんです。文字クラスに
足したり引いたりするだけでそんなこと出来ますか?
「~%7E」は「~~」にしたいです。
そのままにしたい文字(「/」のような)と統一したい文字
「~」のような)を区別する基準は、RFC2396のunreservedに
含まれるか否かです。

たとえば「/%7Ehoge」と「/~hoge」は同じURIだから、
この変換を掛けた後はどちらも同じ文字列にしたいけど、
「a/index.html」と「a%2Findex.html」は違うURIだから
同じになっては困るということです。
0663nobodyさん02/10/01 15:42ID:???
>>662
my %reserved = map { unpack('H2',$_) =>1 } qw(; / ? : @ & = + $ ,);
s/%([0-9A-Fa-f][0-9A-Fa-f])/$reserved{lc $1}?"%$1":pack('H2', $1)/eg;
こんなとこか?
0664nobodyさん02/10/02 03:14ID:???
>a%2Findex.html
このURL自体がありえないと思う。
0665nobodyさん02/10/02 12:06ID:???
>>664
Mac OS 9のサーバなら十分にありうる。
RFC 2396的にも別に禁止されてない。
0666nobodyさん02/10/02 12:07ID:???
つか / が気に入らないなら別の文字当てはめてみろよ。
# と %23 が同一視されたらまずいのは明らかだろ。
0667nobodyさん02/10/06 00:18ID:uZEZ57G8
もっとも後ろにある , 以降の文字列を削除する正規表現を教えてください。


12345,67890,12345,67890 → 12345,67890,12345
aaa3,5567,3333333,aser567 −> aaa3,5567,3333333
dser6f,ghhs,,asfa,wfdw,,,,asf -> dser6f,ghhs,,asfa,wfdw,,,
0668nobodyさん02/10/06 00:21ID:???
s/,[^,]*$//;
0669nobodyさん02/10/06 00:36ID:???
>>668
thx
0670nobodyさん02/10/06 01:34ID:uZEZ57G8
連カキスマソ。
6個目の , 以降の文字列を削除する正規表現について。


11111,22222,33333,44444,55555,66666,77777
 → 11111,22222,33333,44444,55555,66666

11111,222,33333,4444444,55,6 → (これはそのまま)

,,,,,,,,,,11111 → ,,,,,

この正規表現を作ってみたんですが

s/([^,]*)(,[^,]*)(,[^,]*)(,[^,]*)(,[^,]*)(,[^,]*).*/$1$2$3$4$5$6/;

もっとスマートな書き方ありませんか?
0671nobodyさん02/10/06 01:49ID:???
s/([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*.*/$1/;
0672nobodyさん02/10/06 01:49ID:???
括弧を消しすぎた
s/([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*).*/$1/;
0673nobodyさん02/10/06 02:10ID:???
s/^((?:[^,]*,){5}[^,]*).*$/$1/;
0674nobodyさん02/10/06 02:12ID:UBZ5BN7L
chop($st = $1) if $st =~ /^((.*?,){6})/;
とか。
0675名無しさん@Meadow02/10/06 02:15ID:???
>>674
くそ、さき越された。早く寝ろてめえら。
0676hmk02/10/06 02:15ID:???
>>674
キャ〜カッコイイ!!
0677nobodyさん02/10/06 02:18ID:uZEZ57G8
>>674 の案を頂き。thx
0678名無しさん@Meadow02/10/06 02:35ID:???
>>674
しかしだな、
$st =~ s/^((.*?,){6}).*/$1/;
の方が普通やね。やっぱ、俺の方が(略
0679nobodyさん02/10/06 02:41ID:???
>>678
末尾に残るカンマの処理はどうお考えで?
0680名無しさん@Meadow02/10/06 02:53ID:???
>>679
む、やっぱ、あんた=>>674?の方が(略
0681nobodyさん02/10/06 02:57ID:QWnMytEq
サクラエディタで、JSP/ASPのスクリプト部分を色指定しようと試しているのですが巧くいきません。
<%.*%>でオーケーとか軽く考えていたのですが、.は改行文字にはマッチしないのですね。
改行文字も含めてとにかく全部マッチさせるにはどうしたらいいのでしょうか?

#サクラスレではレスが付きませんでした(T_T)
0682nobodyさん02/10/06 03:16ID:???
>>681
改行コードに色は付きません。
改行コードの正規表現は、
windows: \r\n, unix: \n, Mac]\r
です。
0683nobodyさん02/10/06 03:17ID:???
あ、×Mac]\r -> ○Mac: \r
0684nobodyさん02/10/06 03:25ID:???
htmlで改行コードを表示するんなら、682、683で書いた
ものに代替文字を当て、そいつに色タグを付けるようにしる。
0685nobodyさん02/10/06 03:53ID:QWnMytEq
>>682
ごめんなさい、ちょっと書き方が悪かったですね。
<%.*%>と指定しても、<%と%>に挟まれた文字に色がつかないんです。
それで、改行が挟まっているのでマッチしないのか、と思い>>681を書いたのですが……

私、根本的に間違っているのでしょうか?(^^;
0686nobodyさん02/10/06 04:07ID:???
>>684
そいじゃ、「改行文字も含めてとにかく全部マッチさせる」じゃなくって
「改行文字を除いた部分にマッチさせる」じゃねーかよ。日本語大丈夫?
<%.*%>の中に改行が入っているかどうかなんて見れば分かるだろ。
それが確かに原因だと確かめられてから質問しろ。改行を挟む文字列を
連結するにはどうすればいいですかってな。
質問の仕方じゃ、どっかでレスが付かなかったのも当然だよ。


0687nobodyさん02/10/06 04:31ID:???
/<%.*%>/s;
とかいうレベルの話じゃないの
0688nobodyさん02/10/06 04:34ID:???
質問の仕方じゃ→こんな質問の仕方じゃ
我はもう寝る
0689nobodyさん02/10/06 04:35ID:???
ってPerlじゃないのか
0690nobodyさん02/10/13 00:14ID:w3kn3Su/
Perlの正規表現で
0から始まらない数字だけの文字列
ってどう表現すればいいですか?
※001とか0930とかは駄目ってことです。
0691nobodyさん02/10/13 01:08ID:???
/^[1-9]\d*$/
069269002/10/13 01:19ID:w3kn3Su/
↑あーなるほど!
ありがとう!
0693nobodyさん02/10/13 16:39ID:PvvO3hVH
%cat hoge.txt
人数:5725 過去のイベント

から
5725をとるのに
sed -e 's/.*://' hoge.txt |perl -pe 's/\s+.*//;'
としてますが、perlで一つの正規表現でやりたい
0694nobodyさん02/10/13 16:41ID:???
/人数:(5725) 過去のイベント/;

なんと $1 にセットされます。
0695 ◆gst6v8LC9k 02/10/13 18:40ID:???
ユーザが入力したURLの中に
../
がはいっているとイヤです。取り除きたいと思います。
一方、
.. や / は取り除きたくありません。

単純に、
../ を消す正規表現を採用したところ、
たとえば
..././ を入力されたときに、
../ が残ってしまいます。

何か良い知恵はありませんか?

0696 ◆gst6v8LC9k 02/10/13 18:42ID:???
なくなるまでぐるぐるまわさなきゃダメでしょうかねぇ?
0697nobodyさん02/10/13 18:52ID:???
1 while s/\.\.\///;
0698nobodyさん02/10/13 21:54ID:???
>>697
何で?s/\.\.\///g;でいいじゃん。
0699nobodyさん02/10/13 22:01ID:???
>>698
$_= '..././aaa';

これの実行結果を見てみ
070069802/10/13 22:10ID:???
>>699
 (;´Д`)  スミマセンスミマセン
 (  八)
   〉 〉
0701nobodyさん02/10/14 02:49ID:???
いやそれより
..././aaa

aaa
になるのは正しいのか?
.../aaa
にならなきゃならないと思うんだが。
0702nobodyさん02/10/14 03:01ID:???
ああユーザーの入力から取り除きたいってことか
2ちゃんねるの&rlo;対策も>>698と同じ罠にはまってたなそういえば
070369802/10/14 11:30ID:???
>>695の問題設定に矛盾あり。
../を取り除きたいと/は取り除きたくないとの両立は不可能。
ネタか?
0704nobodyさん02/10/14 15:40ID:???
../ 以外の場所に出現する / は取り除きたくないってことでしょ。
つまり ../a/b..c は abc じゃなくて a/b..c にしたいと。
070569802/10/14 16:01ID:???
じゃあだよ、..../..././は?
第1っ回目で..../となり2回目で..かい?
どういう意味があるのかいまだ和歌ら図・・
0706nobodyさん02/10/14 16:06ID:???
それ以前に..../..././にどういう意味が・・・
070769802/10/14 16:17ID:???
>>706
あっしに言ってんの?
じゃ、.../..././でもいいよ。
これは、.になっちゃうよね。それに何の意味があるのって聞いてんの。
070869802/10/14 16:18ID:???
>>706
>>701が言ってることに答えくれればいいんよ。
0709 ◆qOV1uU.npY 02/10/14 16:32ID:???

名前を失念したので、うまく◆gst6v8LC9k になるかどうか不明ですが
695です。失礼しました。皆さんお知恵をありがとうございます。

結局、以下を使う事にしました。
while($blah =~ /\.\.\//){ $blah =~ s/\.\.\///; }

まだ良く読んではいませんが、以下をこれから勉強してみようと思います。
http://b0iler.eyeonsecurity.org/tutorials/perlfilters.htm

0710 ◆gst6v8LC9k 02/10/14 16:36ID:???
こっちだったかなぁ?名前。695です。

ところで、709でのリンクは今さっき見つけたのですが
関連するページを語如語如していましたら、以下のページが親ページ
だったみたいで。
http://b0iler.eyeonsecurity.org/tutorials/hackingcgi.htm

(名前、失敗したら次からは695です、と言おう)
0711nobodyさん02/10/14 17:13ID:???
このお題はかなり勉強になったと個人的に思う。
用はこれ
&rl&rlo;o;
にどう対処するかってことだよね。
早速自分の掲示板書き換えてきます。
0712nobodyさん02/10/14 17:15ID:???
>>711
まずった。
これね
&rl&rlo;o;
0713218-228-157-71.eonet.ne.jp02/10/14 17:53ID:u7YCuldt
(;´Д`)ハァハァ
0714nobodyさん02/10/14 18:26ID:???
ここはCGIの話をするところではありません。
>>709->>712は早急に立ち退いてください。
0715nobodyさん02/10/14 19:00ID:???
はい、次々ぃ!

与えられた文字の並びの中から、
UUENCODEでファイルの記述になっている部分【だけ】を
正規表現でネグるやり方はありますか?

これ、テキストメールでOEユーザあたり宛に、ファイル送るときに
便利ですが。フィルターするならどうします?

掲示板に投稿されたテキストが、まんま、掲示板管理者に送信される
ケースで、事故が発生したことがあります。ちなみにOTDの掲示板で。
今は対処済みのようなんですが、いったいどうやったんだろうと不思議で。

0716nobodyさん02/10/14 19:21ID:???
>>715
「UUENCODEでファイルの記述になっている部分【だけ】を」
日本語がはっきりしませんが、uuencodeされた部分は、beginn
とendで境界付けられています。
0717nobodyさん02/10/14 23:51ID:???
1.undef $/;$while_lines=<>;
2.@lines=<>;
perlを1.2.のような使い方で
a
b
c
d

a\tb
c\td
にするにはどのように書けばいいでしょうか。
s/\n/\t/;
と書く場合、
置換される回数を指定できればやりたいことが実現できるのですが、
そういう手段perlはs演算子に用意されていないと思います。

他の手段でも構わないので、何かアドバイスありませんか?

0718nobodyさん02/10/15 00:00ID:???
s/\n(.*\n)/\t$1/g;
0719nobodyさん02/10/15 00:13ID:???
>>717
undef $/;
$line=<>;
$line =~ s/((.+?)\n(.+?\n))/$2\t$3/g;
print $line;
072071902/10/15 00:16ID:???
>>718の方がおり降参でした。

072171902/10/15 00:35ID:???
でも、漏れだったら、
while(<>) {
chomp;
if ($. % 2) {
print $_, "\t";
} else {
print $_, "\n";
}
}
かなぁ。
0722nobodyさん02/10/15 00:48ID:???
>>721
しょぼいコードだな
072371902/10/15 00:59ID:???
じょぼくて悪かったな。
実は自分でもしょぼいなぁと、>>717はいい質問してくれたなぁと。
■ このスレッドは過去ログ倉庫に格納されています