正規表現道場@2ch
レス数が900を超えています。1000を超えると表示できなくなるよ。
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さん辺りが書いてくれるカモ・・・・
0837声域表現
02/10/25 18:12ID:fEObcI9/ありがとうございます。
これを元にがんばってみたいと思います。
0838nobodyさん
02/10/25 21:17ID:I2JNYDvhなんとピンクローター300円から♪
マニアック商品などその他いろいろあります!
http://www.king-one.com
0839827
02/10/25 22:48ID:???ああ、やりたいことが確かに判りませんね。
迂闊でした。
改めて、質問いたします。
レコード区切りとなるものが存在せず、
2002.10.19
などの日付にマッチさせ、その前の行は空白を残して、
それ以外の空白を消すということです。
つまり、
\n\n\d\d\d\d\.\d+\.\d+.*
のようなものが区切りのキーになると思います。
0841Weasel
02/10/26 18:30ID:lT7ooPWdいるのですが、やり方がわかりません。
> 127.0.0.1 - - [10/Oct/2000:13:55:36 -0700]
> "GET /apache_pb.gif HTTP/1.0" 200 2326
> "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"
というログフォーマットを
・IPアドレス
・日付
・時間
・ファイル
・処理コード
・バイト数
・参照元
・エージェント
でCSVにしたいのですが・・・
だれか教えてください。
0842nobodyさん
02/10/26 18:59ID:???0843nobodyさん
02/10/26 19:54ID:lT7ooPWdCSVってカンマで区切ったフォーマットのことですよね。
Apacheのログは基本的にスペース区切りなのですが、
単にスペースをカンマ(,)に置き換えると、GET /index.html
の中のスペースが区切られたり、いらない「”」が入ったり、
と困っているわけです。また、日付と時間を別のフィールド
にしたいので、正規表現を利用してきちんと指定したいのです。
今は
1 行を読み込む
2 - - [ を削除
3 日付の「2000:」を「2002,」に変換する
4 -9000] を削除
5 「"GET 」を削除
6 ダブルクォーテーションを削除
した上でスペースをカンマに変えてCSVにしています。
これを世紀表現を利用して、もっとスマートにしたいのです。
よろしくお願いいたします。
0844nobodyたん
02/10/26 20:39ID:???= m{(\S*) \s+ # remote
(\S*) \s+ # ident
(\S*) \s+ # user
\[(.*?)\] \s+ # datetime
"(.*?)" \s+ # request line
(\S*) \s+ # status
(\S*) \s+ # size
"(.*?)" \s+ # referer
"(.*?)" # user agent
}x;
とでもした後、適当に変形すれば良いだろ。
0845Weasel
02/10/26 20:47ID:lT7ooPWdありがとうございます。早速試してみます。
0846nobodyさん
02/10/26 22:48ID:???正規表現だけで解決できるかどうかわかりませんが、
あるディレクトリにcsvファイルが
data01.csv
data02.csv
……
data10.csv
のように存在しています。
これを
perlなどで処理したい場合、これらのデータをファイル読み取りのところで、
配列の配列の配列やハッシュのハッシュのハッシュ
という3次元データー構造に変換しなければ、その後のプログラミング
が煩雑になりそうで、いままで、ずーと避けてきました。
厨な私は、普段はこれをエクセルで処理してるんですが、
いっそのこと正規表現で処理してしまえないでしょうか?
なにかアドバイスありますか?
0848Weasel
02/10/27 00:52ID:5TH4jHN51 ディレクトリ下のファイル名を<*>で取得
2 ファイルを開く
3 tempファイルにファイル名と一緒に一行ずつ書き出す
4 ファイルの数だけ2と3を繰り返す
5 まとまったtempファイルを処理する
てな感じではどうでしょうか? とは言うもののdata01〜10.csvの
違いがわからないのですが?
0849Weasel
02/10/27 01:07ID:5TH4jHN5すみません。これPerlでしょうか?
m{ ... }x;
という書式の意味がわからないです。読み込んだ
ログファイルはどの変数に格納すればよろしいの
でしょうか?
大変あつかましくて恐縮ですが、何卒ご教授お願い
します。
0850nobodyさん
02/10/27 02:25ID:???は質問してもしかたないけど
perl式→説明
は「おしえて君」
ですよ。自分で調べられるでしょう。やりたいこと→perl式
は質問していいけど、
perl式→説明
は自分で調べられるでしょう。
0851nobodyさん
02/10/27 02:45ID:5TH4jHN5失礼しました。会社にラクダ本があるので、
月曜日に調べてみます。
0852nobodyさん
02/10/27 03:15ID:???/xモディファイアは、正規表現の中にスペースとかコメントが
入るのを許すもの。m{...}は、デリミタを(デフォルトの"/pat/"
だと"/"をエスケープしなきゃいけなくなるので)"{pat}"にするよ、
とういうことでつな。
>読み込んだログファイルはどの変数に格納すればよろしいの
>でしょうか?
普通に読み込めば?
open LOG, "hoge.log";
open OUT, ">fuga.csv";
while(<LOG>){
#844さんのコード
#その他必要な処理
print OUT "$remote, $ident, $user, ・・・\n";
}
close OUT;
close LOG;
みたいな感じで。
0854Weasel
02/10/28 02:01ID:pNQg1CBu>852
情報ありがとうございます。これってPerlの省略形だった
のですね。
1 変数の記述省略
while (<LOG>) {
print;
}
という指定は
while ($xx = <IN>) {
print $xx;
}
という指定と同じことなのですね。私は常に変数を記述していた
(もっというと、配列に読み込んでforeachを使用していた)ので
わからなかったです。
2 m{ ... }x; について
これが正規表現だということに気づきませんでした。
私はいつも
$ =~ s#abc#def#x
という形で利用していたので、上記のような指定ができることを
知りませんでした。
もっと勉強します。本当にありがとうございました。
0855nobodyさん
02/10/28 09:19ID:???正規表現にて日本語以外、ってどのように指定したらいいんでしょうか。
英字、数字、空白文字はOKで、日本語のみだめ。
jcodeとかつかわないとムリなんでしょうか?
0856nobodyさん
02/10/28 13:02ID:???0857827
02/10/28 15:19ID:???返事が遅くなりました。
0858nobodyさん
02/11/02 05:32ID:I/qwWelh/bbb
/aaa::bbb/ddd
/bbb/ccc::ddd
つまり
/aaa::bbb
/bbb
等の繰り返し
# aaa:: は省略可能です。
などにマッチさせようとしてるんですけど駄目っす。
助けてください。↓今のとこ、こんな感じ
(/([^:/]+::)?[^:/]+)+
かなり的外れっぽいですが(汗
0859nobodyさん
02/11/02 13:39ID:???0860859
02/11/02 14:31ID:???/^(?:\/(?:[a-z]+::)*[a-z]+)+$/;
● / と : 以外の文字が[a-zA-Z_]なら
/^(?:\/(?:\w+::)*\w+)+$/;
0861858
02/11/02 16:22ID:I/qwWelh目的としているのは、>859見たいな奴ですが、
Invalid regular expressionとか出てしまいました(;_;
regex.cで(GREP?SED相当?)最終的にできればいいんですが。
どうも
?:
のとこでコケテます。
ちなみに、
いいい::あああ/ううう
とかも可能にしたかったりします。
あああ、いいい、ううう
に入れられる文字は:と/以外といった感じで。
0862nobodyさん
02/11/02 16:45ID:ywtiXWSTstr1,str2,str3(str4,str5,str6)str7,str8,str9 なら str4,str5,str6 だけ
"," → "," と変換したいのですが、
どういう文にすればいいですか?
s/\(([^\)]+),([^\)]+)\)/\($1,$2\)/g;
を何回か繰り返すことで何とか済ました(本当か?)のですが、
まともなやり方を知りたくなりまして。
0863858
02/11/02 16:53ID:???は、部分正規表現のグルーピングなんですね。(レポートなし。
ということはこれは外してみて、
/^(\/([a-z]+::)?[a-z]+)+$/;
で、やってみたら通ったけどマッチせずでした。
薄識なんで、\/と最後の/の意味がわからないっす。
0866865
02/11/02 17:03ID:???1 while s/(\([^),]*),/$1,/g;
0867nobodyさん
02/11/02 17:40ID:???[aa]
[aa[]
[aa[]]
から
[aa]
だけ許すみたいな。
単純に
\[[^\[\]]+\]
でやったら
[aa]にはかからず、[aaa[]]に引っかかっちゃいました。
Perlで試したら1だけOK、他はマッチしなかったけど?
0870perl初心者
02/11/02 22:24ID:???#! /usr/bin/perl
@set= ("[aa]","[aa[]","[aa[]]");
foreach $value (@set){
if($value =~ /\[[^\[\]]+\]$/ ){
print "$value\n";
}
else{
print "not match\n";
}
}
PostgresのPOSIX正規表現で試してて、まぁ実際はregex.cで使う
予定だったので又実際に試してみましす。
0871870
02/11/03 21:50ID:???#include <regex.h>
int main(int argc,char *argv[])
{
int i;
regex_t preg;
char *pattern = "^(\\[[^\\[\\]]+\\])+$";
puts(pattern);
/* Complile RE Pattern */
i=regcomp(&preg,pattern,REG_EXTENDED|REG_NEWLINE|REG_NOSUB);
if (i != 0){
puts("error\n");
return 1;
}
puts(argv[1]);
/* Evolute RE */
i = regexec(&preg,argv[1],(size_t) 0, NULL,0);
regfree(&preg);
if(i != 0 )
puts("no match\n");
else
puts("match\n");
return 0;
}
0872870
02/11/03 21:50ID:???うう、駄目っす(;_;
echo "[aaa]" | egrep "^(\[[^[]+\])+$"
ちなみに、
char *pattern = "^(\\[[^[]+\\])+$";
だと、
○[aaa]
○[aaa]]
×[aaa[]]
まで通る
ので、たぶん、[と]のエスケープが駄目のようなんですが。
perlのREって独自の実装だから通るって話ですか?
Rubyとかはgnu regex使ってると思うのでたぶん通らない(?
ここより、Cスレの方が適切かもしれんけどよろしこ!
0873870
02/11/03 22:12ID:RYsGgBBRage!
0874nobodyさん
02/11/04 00:20ID:5X7nKz+P"foo bar" =~ /f*/ # => <<f>>oo bar
"foo bar" =~ /o/ # => f<<o>>o bar
"foo bar" =~ /o*/ # => <<>>foo bar
ruby でどこにマッチするかを表示させてみたのですが、
/o*/が先頭の空文字とマッチするのがどうも分かりません。なぜでしょうか。
f<<oo>> bar とマッチすると思っていたのですが。
0875874
02/11/04 00:25ID:5X7nKz+P0876870
02/11/04 06:13ID:???http://www.kt.rim.or.jp/~kbk/regex/regex.html
(\\[([^][])+\\])+$
でやったらでけますた
0877nobody
02/11/04 06:52ID:???質問には答えません。
0878nobodyさん
02/11/05 13:21ID:???北尾邦伸 (1998) 風土・文化の伝承の場としての里山. ランドスケープ研究 61: 287-289.
横張真 (2000) 国内外の農政における環境保全の位置づけ.ランドスケープ研究, 63(3), 182-185.
加藤和弘・一之瀬友博・大久保悟 (1997) 都市近郊におけるコナラ林の組成および構造について.ランドスケープ研究, 60(5), 539-542.
のような参考文献一覧があり、
「ランドスケープ研究, 60(5)」の「60(5)」という数字で並び替えたいんですが、
やり方判る方いらっしゃいますか?
ランドスケープ研究の次は、スペースの時と、カンマ(, )の時とが、混在しています。
なお、もとデータはhttp://homepage.mac.com/hitou/satoyama/bunken.htmlから「ランドスケープ研究」というキーワードでgrepしたものです。
0879878
02/11/05 14:42ID:???-----
もとデーターは
http://www.ss.iij4u.or.jp/~osamu-s/bibliography.htm
と
http://ime.nu/homepage.mac.com/hitou/satoyama/bunken.html
で作ったファイルをgrepしたものです。
0882878
02/11/05 15:37ID:???それから、僕はタグはw3m -dumpしました。
0883nobody
02/11/05 21:49ID:???これはどう?
while(<>) {
$landscape{$1} = $_ if /\Qランドスケープ研究\E.+?(\d.+)/;
}
foreach $key (sort {$a <=> $b;} %landscape) {
print $landscape{$key};
}
sjisでやるときのために、\Q\E入れますた。
0885nobody
02/11/05 22:38ID:???よかったっすね。
ところで、書き込んでから後で気づいたんだけど、昇順ソートにもかかわらず、
61: 296-298.の方が61: 287-289.より前に来ちゃうのよね。どしてー?
"61: xxx-xxx"の61しか見てないからだよ。
0888nobodyさん
02/11/06 22:30ID:???0890nobodyさん
02/11/07 10:52ID:hTcjcUGC/から/までをイタリック
#hello# -> <b>hello</b>
/hello/ -> <i>hello</i>
s|#(.*?)#|<b>$1</b>|g;
s|/(.*?)/|<i>$1</i>|g;
としてましたが
#hello/nest#hello/
ってのがきちゃうと
<b>hello<i>nest</b>hello</i>
ってなっちゃいます。
<b>hello<i>nest</i></b><i>hello</i>
ってしたいんですけどスマートな解決法ありませんでしょうか?
0893nobodyさん
02/11/07 15:20ID:???29から44までの数字ってどう表しますか?
for(29..44)は使わないで、表現してください。
0894nobodyさん
02/11/07 16:09ID:???0895nobodyさん
02/11/07 16:09ID:???/29|3[0-9]|4[0-4]/
0896教えて偉い人
02/11/07 19:37ID:???で、
[@ [@ xx @] @] <= 本文
1__2_____3__4 <= 話をわかりやすくするための括弧の通し番号
こんな風になったとき、最短の [@ xx @] (番号 2と3 )を取り出したいのですが
最短一致で [@ .+? @] としても [@ [@ xx @] (番号 1と3 )が取り出されます。
どうすればいいのでしょうか....
なお、xx の変わりに @ や [ や ] が単独で入る可能性はあるので、
[^@\[\]]+? は使えません
ちなみに jscript です
0897nobodyさん
02/11/07 21:05ID:F/lYrXVu"^([a-z0-9_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,4}$"
"\"がふたつ続いている部分は、意味があるのでしょうか。
"\"をひとつにしてもちゃんとマッチしたのですが…。
0898nobodyさん
02/11/07 21:29ID:???ある
> "\"をひとつにしてもちゃんとマッチしたのですが…。
気のせい
0899nobodyさん
02/11/07 21:53ID:???これでもマッチしますた。
<?php
$mail = "a.b-.c@a.b--b.cc";
if(eregi("^([a-z0-9_]|\-|\.)+@(([a-z0-9_]|\-)+\.)+[a-z]{2,4}$",$mail)) echo "yes!";
?>
どんな場合に"\\"が意味を持つのでしょうか。
0900nobodyさん
02/11/07 22:04ID:???マッチすべきでないものにもマッチしないか?
あくまで稚拙なテストでうまく動いてると言い張るなら勝手にしろ
> どんな場合に"\\"が意味を持つのでしょうか。
そんな場合
0901nobodyさん
02/11/07 22:38ID:???"\\"の意味を教えていただけないでしょうか。
正規表現のリファレンスページでは見あたらなかったので、
"\\"というくくり方(捉え方)がそもそも違うのかもしれませんが、
わたしの聞きたいところはご理解いただけないでしょうか。
0902nobodyさん
02/11/08 01:21ID:???0903nobodyさん
02/11/08 02:00ID:???"\."は"."そのものを表し、"\\."なら"\"と任意のひと文字にマッチする…。
ということになるのですが、>>897の場合は違いますよね…?
どう違うのでしょうか。
0904nobodyさん
02/11/08 02:12ID:MLOzQJLMs{(?:#(.*?)#)|(?:/(.*?)/)}{
"<b>$1</b>" unless $1 eq undef;
"<i>$2</i>" unless $2 eq undef;
}ge;
これだと
#hello/nest#hello/ は
<b>hello/nest</b>hello</i> か。
invalid な HTML 吐かないだけマシって考えてください。
0906nobodyさん
02/11/08 03:00ID:1u/BJa8n0907897
02/11/08 03:57ID:???わたしは905さんとほぼ同じように考えています。
ただし、"\\."だと、"\."という文字列ではなくて、
文字列としての"\X"とか、"\0"とかにマッチする、
つまり、"."は正規表現として扱われるのではないか、と。
そうだとすると、メールアドレスに"\"なんて含まないじゃないか、
なんて思ってしまうわけです。
906さんもヒントなのでしょうか?
***@2ch.netだと、"*"がマッチしないので、ダメですよね。
("\"のときも"\\"のときも)
abc@2ch.netにしてみましたが、当然マッチします。
("\"のときも"\\"のときも)
0908nobodyさん
02/11/08 04:03ID:???"\\" → /\/
"\\." → /\./
?
0911>>897
02/11/08 17:02ID:4bJRaQIX'^([a-z0-9_]|\-|\.)+@(([a-z0-9_]|\-)+\.)+[a-z]{2,4}$'でしょ?
"^([a-z0-9_]|\-|\.)+@(([a-z0-9_]|\-)+\.)+[a-z]{2,4}$"にしたら
'^([a-z0-9_]|-|.)+@(([a-z0-9_]|-)+.)+[a-z]{2,4}$'になっちゃうから、
たとえば「"@a>aa」などにもマッチするのでは?
0912897
02/11/08 19:47ID:7pCyPVrIえと、無駄なものもあるのかもしれませんが、
$mail = 'a@a>aa';
$mail = '"a@a>aa';
$mail = '\"a@a>aa';
$mail = '"a@a\>aa';
$mail = '\"a@a\>aa';
以上のすべての$mailの場合で、
if(eregi("^([a-z0-9_]|\-|\.)+@(([a-z0-9_]|\-)+\.)+[a-z]{2,4}$",$mail)) echo "yes!";
以上の判別にマッチしませんでした。(yes!と表示されない)
もちろん
$mail = 'a@a.com';
ならマッチします。
0913897
02/11/08 19:52ID:???正規表現として読まれる前の正規表現というか、
"\."をもう一度正規表現として読むと、
正規表現としての"."になってしまう、という意味ですよね。
でも、実際はそういう、二段階で読まれる構成にはなっていないようです。
わかりにくくしか書けなくてすみません。
0914nobodyさん
02/11/08 20:52ID:+kBzeIscたとえば、制限文字数20文字だとして、
http://dailynews.yahoo.co.jp/fc/science/astronomy/
↓
<a href="http://dailynews.yahoo.co.jp/fc/science/astronomy/>
http://dailynews.ya...
</a>
こんなのを考えてるんですが・・・
0915nobodyさん
02/11/08 21:37ID:???ttp://itp.ne.jp/servlet/jp.ne.itp.sear.SCMSVTop
タウンページでの検索結果を
CSVなどの構造化されたデータに変換する最も一般的な手段は
何でしょうか?
ぼくは今まで、w3m -dump →正規表現
と回してましたが、直接HTML読んでCSVなりに変換されている方
いらっしゃいませんか?
0918914
02/11/08 21:53ID:???phpでやってるんですが、
$text = eregi_replace(
"(http://[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]?)".
"[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%#]*",
'<a href="\0">\1</a>', $text);
こんな感じのでできました。
果てしなくコードきもいけど。
もっとスマートな方法あるんでしょうか。
0919914
02/11/08 21:56ID:+kBzeIscいや、ほら、
掲示板で半角でhttpって打つと、
勝手にリンクに変換されてうざいじゃないですか。
0920nobodyさん
02/11/08 22:22ID:t0LygGS2{1,20}を使う。後は分かるはず
0921nobodyさん
02/11/08 22:25ID:???だーからー、
http://dailynews.ya...
は、20文字制限って言ってるのに24文字でしょ、
もしかして、マルチバイト対応での話?
0922920
02/11/08 22:34ID:t0LygGS2だーからー、
本当はソレは半角なんだが、
ここ(2ちゃんねる)では勝手にリンクに変換されてうざいってことでしょう。
0923914
02/11/08 22:50ID:+kBzeIsc$text =
preg_replace("#ftp://([-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%\#]{1,16})[-_\.!~*'()a-zA-Z0-9;/\?:@&=+$,%\#]*#i",
'<a href="\0">\1</a>',
$text);
>>912 そうです。
できれば、「20文字以上を越えたら"..."つける」っていう機能もほしいな、
とか、思ったりしたり。。。。
0924nobodyさん
02/11/08 22:55ID:???「20文字を超えたら」のところはif文との組み合わせでしょ。
0925nobodyさん
02/11/08 23:01ID:???だーからー、じゃなかった、
そーれじゃー、
sedとかPerlで
s/(<a href=\")(http:\/\/.............)(.+>)(<\a>)/$1$2$3$2$4/;
かいな。sedでは\1, \2 ...だったけや。
0926nobodyさん
02/11/08 23:14ID:???0927914
02/11/08 23:32ID:???みんなPerl派なのかな。
はて、どうしようか。
0928914
02/11/09 00:13ID:???function e_modifier($match){
if(strlen($match[0]) > 20){
return "<a href=\"$match[0]\">".substr($match[0],0,20)."…</a>";
}else{
return "<a href=\"$match[0]\">".$match[0]."</a>";
}
}
$text = preg_replace_callback("|gopher://[-_\.!~*'()\w;/\?:@&=+$,%#]+|i", 'e_modifier', $text);
結構ながくなっちったなあ。
それにしても、完結に書ける分Perlはいいなあ。
>>926 さんのやつかっこいいコードです。
0931nobodyさん
02/11/10 16:03ID:???0932nobodyさん
02/11/11 20:19ID:sWg+L5qaとすると、数字がないときに$1に変な文字が入るのですが
どうすれば入らないようにできますか。
0933nobodyさん
02/11/11 21:43ID:???}
0936nobodyさん
02/11/12 23:51ID:???my $foo = 'A';
$var =~ /(\d)/;
print $1, "\n";
$foo =~ /(\d)/;
print $1, "\n";
1
1
つうことじゃないの?
何で何をどうやってるのかわからんけど。
レス数が900を超えています。1000を超えると表示できなくなるよ。