トップページ⇒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さん辺りが書いてくれるカモ・・・・
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はいい質問してくれたなぁと。
072471702/10/15 01:52ID:???
あ、実は
a b c
d e f
g h i
j k l
とかも作る必要があったので、721のものが一番
良かったかも。

汎用性?
072571902/10/15 02:04ID:???
>>724
あんた優しいね。好きっ
0726nobodyさん02/10/15 02:53ID:epeKbC4J
携帯アドレスはハネない程度に厳しいメアド判定教えて!
0727nobodyさん02/10/15 03:22ID:???
@以下のアドレスに対して、whois
072872602/10/15 10:55ID:Hi0tGOTs
>>727
正規表現のみでひとつ
0729nobodyさん02/10/15 11:00ID:LkwD4Abx
>>726
/[-_.a-zA-Z0-9]+@(?:[-a-zA-Z0-9]+\.)?[-a-zA-Z0-9]{3,63}\.(?:[a-z]{2,}\.[a-z]{2}|[a-z]{2,})/
0730nobodyさん02/10/15 12:28ID:???
誰っかー。助けてください。
某サイトでお願いして書いてもらったソースコードを実行するたびに、
掲示板が勝手に改行いれるので、それを消し去る正規表現を書きたいです!!!

規則は:
1.全ての行は本来ならスペースやタブで始まる
2.勝手に改行されていた行は先頭(^)から始まる
3.本来なら、各行の先頭は大文字である
4.勝手に改行されていた行は先頭が小文字である

ぐらいかな〜。


具体例:
    Cells.Find(What:="場所", After:=ActiveCell, LookIn:=xlValues, Look
At:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchC
ase:=False) _
.Activate
のような感じです。お願いしました。
073173002/10/15 12:30ID:???
あ、
3.本来なら、各行の先頭は大文字である
4.勝手に改行されていた行は先頭が小文字である
には例外があるみたいです。

御願いしましたよ。
0732nobodyさん02/10/15 14:22ID:???
*は全て半角数字です。「-」は文字としてのハイフンです。
文字のパターンは、
1:****** # 文字数未定の1文字以上の半角数字
2:***-*** または、 ***-***-***  # 文字数は未定の数字のあとにハイフンが入ります。
ハイフンは1個の時と、2個付くときがあります。

例)12344556 、 32-98 、 45-98-35

これらの正規表現をお願いします。
自分で考えたのは
([0-9]+[[\-[0-9]+]?[\-[0-9]+]?) これです。
一応成功するんですが、**-**-**-** こうやっていくつも続いた時も
マッチしてしまいます。基本的に**-**-**という風に三回しか繰り返しません。
修正があればお願いします。
0733nobodyさん02/10/15 14:26ID:???
すいません、正しいのはこれです。
([0-9]+[\-[0-9]+]?[\-[0-9]+]?)/mg)
0734nobodyさん02/10/15 14:29ID:???
/^(?:\d+-){0,2}\d+$/;
0735nobodyさん02/10/15 19:18ID:???
>>715
$in{$_} =~ s/^begin 0{0,1}[0-9]{3} (?:(?!\nend).)*(\nend)/UUENCODED-BINARY/gs;
$in{$_} =~ s/\nbegin 0{0,1}[0-9]{3} (?:(?!\nend).)*(\nend)/\nUUENCODED-BINARY/gs;

うちではこうだけど。でも取り除き漏れがあるかな?うぅーん。
073672602/10/16 21:41ID:lp+sZlkX
>>729
ありがとう
0737nobodyさん02/10/17 02:55ID:???
sage
0738nobodyさん02/10/18 23:47ID:???
正規表現で、
日本語のひらがな一文字だけマッチさせるのって出来るのですか?
0739nobodyさん02/10/18 23:51ID:???
でっ、できちゃう
0740nobodyちゃん02/10/19 01:06ID:???
>>738
jperlなら、[ぁ-ん]
perlなら、sjisの場合、\x82[9F-F1]、
eucの場合、A4[A1-F3]、jisの場合、24[21-73]、utf8の場合、30[41-93]

0741nobodyちゃん02/10/19 01:08ID:???
おや、16進数を表す記号を付け忘れたし。
perlなら、sjisの場合、\x82[\x9F-\xF1]、
eucの場合、\xA4[\xA1-\xF3]、jisの場合、\x24[\x21-\x73]、
utf8の場合、\x30[\x41-\x93]
0742nobodyさん02/10/19 13:03ID:???
ココ見てる人なら、知ってるかも。

HTMLの<TABLE>〜</TABLE>をCSVとかTSVとかに変換できますか?

table2csv.pl
なんてのがあるわけがないと思って質問シマスタ。
w3m -dump はへんな線が入るので、使いたくないし、CSVが勝つよう範囲も
広そうなので、だれか書いていてもよさそう。


とっても困ってます。

0743738 02/10/19 13:16ID:???
>>740

perl(jperl and perl5.8)の
s/あ/ア/;
tr/あ/ア/;
の違いってわかりますか?

たぶん、知ってそうだから。ごめんね。
074474202/10/19 13:36ID:???
http://www2.crl.go.jp/jt/jt221/tfujii/Installer/table2csv.txt
になんかそれっぽいものあるけど
動かない。

理由わかる人いますか?
0745nobodyさん02/10/19 14:01ID:???
>>744
こりゃあ、ひどいな・・・
0746nobodyさん02/10/19 15:15ID:???
>>744



ほれ。区切りはawkだから-F","とかね。


BEGIN { print "<table border=\"1\">";}

{
print "<tr>";
for (i=1; i<=NF; ++i){
gsub(/&/,"\\&",$i);
gsub(/</,"\\<",$i);
gsub(/>/,"\\>",$i);
print "<td>" $i "</td>";
}
print "</tr>\n";
}

END { print "</table>";}
0747744 02/10/19 17:19ID:???
>>746
csv2table.awkではなく
table2csv.awk

が欲しいのです。

074874402/10/19 18:08ID:???
どれくらいのテーブル? どでかいの?
074974402/10/19 18:39ID:???
ちっちゃいですよ。すごく。
0750nobodyさん02/10/19 18:44ID:???
>>744
ファイルから読み込むならまず最初に全部変数に読み込め
0751nobodyさん02/10/19 21:52ID:???
>>742
colspanとrowspanが指定されてるのってどうするかとか、
仕様が決まれば、すぐ書けるよ。特にrowspanね。
caption、thead、tfootどうするかは、たいした問題じゃ
ないな。
libraryやmoduleがないのは、余りにも簡単だからだよ。
perl初心者コーナーで質問したら書いてくれる人いっぱい
いたのにぃ。
0752nobodyさん02/10/19 22:08ID:???
>>751
colspan や rowspan があるテーブルはどうやってCSV変換するんだ?
0753nobodyさん02/10/20 11:10ID:???

例えば、
┌─┬─────┬─────┐
│ │  人間  │  猿  │
│ ├──┬──┼──┬──┤
│ │ 男 │ 女 │オス│メス│
├─┼──┼──┼──┼──┤
│x │ 1.9│ 2.3│ 1.3│ 1.8│
├─┼──┼──┼──┼──┤
│y │ 0.8│ 0.4│ 0.4│ 0.2│
└─┴──┴──┴──┴──┘
だったら、
"," (row: 2)","人間 (cols: 2)","人間 (cols: 2)","猿 (cols: 2)","猿 (cols: 2)","
"," (row: 2)","男","女","オス","メス","
","x","1.9","2.3","1.3","1.8","
","y","0.8","0.4","0.4","0.2","
こんなふうにするスクリプト。改行多くて1レスにならんから、次レスへ。
0754nobodyさん02/10/20 11:10ID:???
>>753の続き
while(<>) {
chomp;
$flg = 0;
$col = 0;
$line = $_;
$line =~ s/(<\/*thead>|<\/*tfoot>)//gi;
$line =~ s|</*tr.*?>||gi;
for $i (0 .. $#row_max) {
undef $row_data[$i] if $. > $row_max[$i];
}
while($line =~ /<(td|th)/) {
$flg = 1;
$col++;
$line = "$'$row_data[$col]$&$`";
if ($line =~ s|<t[dh][^<]+?rowspan.+?(\d+).+?>(.*?)</t[dh]>|"\",\"" . $2 . " (row: " . $1 . ")"|ei) {
$row_data[$col] = "<td>$2 (row: $1)</td>";
$row_max[$col] = $. + $1;
} elsif ($line =~ s|<t[dh][^<]+?colspan.+?(\d+).+?>(.*?)</t[dh]>|("\",\"" . $2 . " (cols: " . $1 . ")") x $1|ei) {
1;
} else {
$line =~ s|<t[dh][^<]*?>(.*?)</t[dh]>|","$1|i;
}
}
print "$line\",\"\n" if $flg == 1;
}
しっかり試してないからバグが潜んでいるかも。
■ このスレッドは過去ログ倉庫に格納されています