トップページ⇒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さん辺りが書いてくれるカモ・・・・
0267名無しさん@お腹いっぱい。02/01/31 23:23ID:XvhUBoWr
変換されてしまった。訂正です。

> "に変換するには正規表現でどう書くんでしょうか?
↓
> "に変換するには正規表現でどう書くんでしょうか?
0268 ◆7P5EE/DI 02/02/01 00:08ID:???
>>261
とりあえず気が付いたことだけ。

1. 繰り返し処理``だけ''を行いたいならgrepやmapではなくforeachを使うのがよろし。
2. データの一部が削除されているので、truncateしてやらんと末尾にゴミがくっ付いてしまう。
0269名無しさん@お腹いっぱい。02/02/01 01:10ID:???
>>266
$str = '<font size="5">冬は"寒い"。</font>夏は"暑い"。';

こんなのしか考えつかない…。正規表現一発で出来るの?偉い人〜
foreach (split /(<[^>]+>)/,$str) {
    !/</ and s/"/&quot;/g;
    print;
}
027026602/02/02 01:23ID:YNNMuvTz
>>269
ありがとうございます。
そこから考えて、汚いですがとりあえずこんなので解決しました。
while ($str =~ s/>([^<]*)"/>$1"/g or $str =~ s/"([^>]*)</"$1</g) {}

もし正規表現一発で出来る方法があったらよろしくお願いします。
0271初心者02/02/02 03:29ID:oZiG+SwX
$str =~ s/\"/&quot\;/g; $str =~ s/<([^\>]*)=&quot\;(\w)&quot\;([^\>]*)>/<$1=\"$2\"$3>/g;

じゃだめなのか。
0272名無しさん@お腹いっぱい。02/02/02 03:58ID:???
URLとかスタイルシートがあるからだめだろうね -> \w
0273 ◆7P5EE/DI 02/02/02 06:05ID:???
一行だけど、なんだか。
こんなんしか出来ませんでした。

$str = join '', map { /^</ or s/"/\@/g; $_ } split /(<[^>]*>)/, $str;
0274 ◆7P5EE/DI 02/02/02 06:06ID:???
訂正。
$str = join '', map { /^</ or s/"/"/g; $_ } split /(<[^>]*>)/, $str;
0275名無しさん@お腹いっぱい。02/02/03 19:17ID:???
正規表現より良い表現(マッチ方法)って無いの?
0276名無しさん@お腹いっぱい。02/02/04 03:27ID:???
マッチョ法ってのがあるよ。
0277名無しさん@お腹いっぱい。02/02/04 03:37ID:???
>276
それどんなかんじ?
0278あぼーんNGNG
あぼーん
0279名無しさん@お腹いっぱい。02/02/04 06:14ID:???
>>277
ぐぐーるしてください。
0280名無しさん@お腹いっぱい。02/02/04 10:37ID:6Yw0Bfwo
>>275
これなんかどうよ?
文脈依存文法表現案
http://www.try-net.or.jp/~yoji/idea/gramagic/codgex.html

まだ案だけど、これが完璧になれば、圧縮ファイル中の html ファイルの
a 要素の href 属性の中で 2ch に関係してるものを検索、
とか出来るようになるのかな。まだ案だけど。
0281名無しさん@お腹いっぱい。02/02/15 04:54ID:???
>>278は何?
0282名無しさん@お腹いっぱい。02/02/15 07:48ID:???
マッチョ法age
028326802/02/16 21:03ID:???
あ・・・そうだ・・・ありがとう。
0284名無しさん@お腹いっぱい。02/02/28 01:43ID:xJe5pzKX
半角スペースは\sでいいんでしょうか?
複数スペースを一個にしたいので
$string =~ s/\s+/\s/g;
とやったらうまくいきません。ていうか
$string =~ s/\s/test/g;
とやっても半角スペースに反応しなかったんですけど、\sの理解が間違ってますか?
宜しくお願いします。
0285名無しさん@お腹いっぱい。02/02/28 01:50ID:???
tr/\x20\x09/ /s;
0286名無しさん@お腹いっぱい。02/02/28 01:52ID:xJe5pzKX
ああ、やっぱりそういうややこしいのになっちゃうのね。ありがとう。
ちなみにどうして284のは間違ってるんですか?
0287名無しさん@お腹いっぱい。02/02/28 01:53ID:???
>284
2番目のは反応したよ。

\sは[ \t\n\r\f]と同意。
半角スペースだけでなく,タブや改行にもマッチする。
0288名無しさん@お腹いっぱい。02/02/28 01:58ID:xJe5pzKX
あやや、それじゃあ僕の試験が間違っていたかな。
もっかいやってみます。ありがとうございました。
028928502/02/28 02:14ID:???
s/pattern/replace/[geoi];
左側のくくりのパターンには\sのような複数の意味をまとめたエスケープ表現は
使えるが、リプレイス部分に複数の意味を持つエスケープを書いても何に置き換えて
いいものかが曖昧になることを考えるとおのずと使えないということがわかります。
したがって、かくならつぎのようにも書けます。
s/\s+/ /g;
s/\s+/\x20/g;
0290名無しさん@お腹いっぱい。02/02/28 02:21ID:xJe5pzKX
なるほどなるほど。そのとおりだ。僕もそう思ってました(笑)。
ところで、
s/ +/ /g;
これじゃあだめですか。いや、だめだったんですけど..。
0291名無しさん@お腹いっぱい。02/02/28 02:32ID:???
>290
Perl5.004でうまくいったよ。
スレ違いぎみなのでsage
029228502/02/28 02:33ID:???
> 290
できるはずなんですが...

$_= 'a   b   c';
s/ +/ /g;
print $_,"\n";
029329002/02/28 02:49ID:???
なんでできないんだー。でもなんか、ド素人なんで疑う要因多すぎなんです。
勉強して出直してきます。ごめんなさい。
0294nobodyさん02/03/05 21:54ID:X1wZ/GVz
長すぎる半角英数等を(省略)と表示されるようにしようと思いましたが、
オートリンクのa要素のhref属性の値まで省略されたので、

$comment =~ s/(<a (.+)>)?(([\w\.\/\:]){20})([\w\.\/\:]){35,}(<\/a>)?/$1$3 \(省略\)$6/g;
と書いたのですが、今度は適用されるのが最後にマッチしたヤツだけになりました。

最後にgを付けてるのに全てにマッチされないのは何故ですか?
また、この記述より(・∀・)イイ!!のがあればご教授ください。
おながいします。
0295nobodyさん02/03/06 00:04ID:???

0296nobodyさん02/03/06 00:18ID:???
>295
なっ、なるほどぉ。

勉強になりました。
029729402/03/06 00:42ID:???
今日はもう、枕濡らして寝ます。枕ないけど。
0298nobodyさん02/03/06 01:41ID:???
>>294
複雑で私の頭じゃあまり理解できなかったのだけど
s/(\w{20})\w{5,}/$1(略)/g;
じゃダメ?
0299nobodyさん02/03/06 01:45ID:???
>>294
試してないけど最初を
<a [^>]+>
にしてみてはどうか?
0300nobodyさん02/03/06 05:25ID:???
>>294
一応できたよ.a要素だけに限らずタグの内側の文字列はいじらないようにしてみた.
つうか思いッきり>>273-274をパクッてます(w.制限は単純に5文字.

$comment = join '',
    map { /^</ or s/([:\.\/\w]{5})[:\.\/\w]+/$1(省略)/go; $_ }
    split /(<[^>]*>)/, $comment;


ついでにファイルから読み込みつつ変換するスクリプトも用意してみたよ.

my ($char, $tail) = (q{[:./\w]}, '');
open IN, "./in.html" or die;
open OUT, ">./out.html" or die;
while (my $comment = <IN>) {
    my @tmp = split /(<[^>]*?>)/, $tail . $comment;
    $tail = ($tmp[-1] =~ /^<.*>$/ ? '' : pop @tmp);
    $comment = join '', map { /^</ or s/($char{5})$char+/$1(省略)/go; $_ } @tmp;
    print OUT $comment;
}
close IN;
close OUT;

↓こんなふうにタグが複数行にわたって記述されていた場合を考慮してます.
<a
 href="http://hoge.hoge.hoge/"
 accesskey="h"
 title="ほげ〜">
030129402/03/06 06:52ID:???
>>297-300
みなさん、ありがとうございます。
300氏の方法で上手くいきました。
教えられた関数等について調べてみます。
ホントにありがとうございました!
0302nobodyさん02/03/08 15:33ID:???
>>297
むしろ
「枕ないけど」にもらい泣き
( ´Д⊂ヽ ウエーン
0303nobodyさん02/03/08 15:38ID:2kUcWket
http://sasurai.gaiax.com/home/tonakari
0304nobodyさん02/03/08 17:26ID:???
>>302
バカヤロウ!あのセリフの後には
「枕ないけど(彼女の膝枕で)」と続くんだぞ!?

…くやし泣き( ´Д⊂ヽ ウエーン
030529402/03/08 21:21ID:???
・・・彼女もいませんが。
( ´Д⊂ヽ ウエーン
0306 02/03/27 11:31ID:zMki/eSS
age
0307nobodyさん02/04/08 22:52ID:qnubSkpk
age
0308nobodyさん02/04/10 00:54ID:???
print $a || $b == 0 ? "●" : "◯";
ってどういう意味なんですか、おしえてください。
0309nobodyさん02/04/10 00:58ID:???
>>308
三項演算子とorだ。

or dieの応用編かつPerl4仕様だ。
0310nobodyさん02/04/10 02:11ID:???
if ($a) {
  print $a;
} elsif ($b == 0) {
  print "●";
} else {
  print "◯";
}
0311nobodyさん02/04/10 02:22ID:???
>308
単に三項演算子の結果を印字してるだけのこと。

>309
なんでここで die が出てくるんだ? あたまの弱い人か?

>310
認識違いもはなはだしい。はなしにならない。価値のない人間か?
0312nobodyさん02/04/10 02:49ID:???
>>311
お前から見て、価値のない人が世の中には多いけど、
それはお前自身の価値が高すぎるからじゃなくて、
お前の価値が、社会の常識とかけ離れているからなんだよ。
0313nobodyさん02/04/10 05:25ID:???
if ($a || $b == 0) {
print '●'
}else{
print '○'
}

print ($a || $b == 0) ? "●" : "◯";
こう書くと誤解がないかも

309は「or dieの応用編だ」といっているわけで
0314nobodyさん02/04/10 07:15ID:???
>>311
たとえ話って言葉を知らない融通の利かない方ですか?
0315nobodyさん02/04/10 12:27ID:???
>>311じゃないが、

print open IO, $a || $b ? "ok" : "not ok";

これを "or dieの応用編かつperl4仕様だ。"といわれりゃ、そりゃ"ハァ?"だろ。

open(IO, $a) || print("not ok");

これならそう言えないこともないが。
0316nobodyさん02/04/10 14:29ID:???
>315
たしかにそうだよね。
or die ってのを応用したものが ($a || $b == 0) ってのは矛盾してるよね。
ってことは、309は 「(print $a) || ($b == 0 ? "●" : "◯");」だと
勘違いしていたのでは?

つまり311の言うあたまの弱い人ってのは図星かも...
0317nobodyさん02/04/10 14:47ID:???
で、どこらへんが正規表現なんでしょうか?

0318nobodyさん02/04/10 15:46ID:???
まあ、釣れた、とだけ言っておきましょうか 藁
0319nobodyさん02/04/11 16:42ID:9/X5PbzJ
あたまの悪い人を除去するせいきひょうげんをおしえて下さい。
0320nobodyさん02/04/11 19:02ID:???
die if /(BASIC|COBOL)/cgi;


0321ぷうすけ02/04/11 22:56ID:KLtv0nPl
顔文字を正規表現で表すには!?
0322nobodyさん02/04/11 23:07ID:???
>>321
ヒアドキュメント
0323nobodyさん02/04/20 18:04ID:wIgJDzcz
漢字、ひらがな、英数文字で、書かれているテキストファイルから、
ひらがなだけを、抽出したいのだが
頭が悪いのでよく分からん、教えてくれ。

テキストファイルの入出力は置いておいて。こんな感じの事が行いたいのだ。

$str = "頭が悪い";
$str = ~/[あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん]/;
print $str,"\n";

頭が悪いのでこのように書いたのだが、実行すると

「頭が悪い」
になってしまうのだ、

本当は

「がい」

を求めたいのだができん。
わしより頭の良い、2チャンネラー達宜しく頼む。
0324nobodyさん02/04/20 18:18ID:???
>>323 = 某研究者
0325nobodyさん02/04/20 20:04ID:???
>>323
# SHIFT_JIS用
my $str = "書き込みえらー出そうだね。";
print $str =~ /\x82[\x9F-\xF1]/g;
0326nobodyさん02/04/20 20:32ID:wIgJDzcz
>>325
すまんが、EUCの時はどうするかついでに教えてくれくれぬか。
頼む。
0327nobodyさん02/04/20 20:48ID:???
>>326
Perlメモを熟読しる。
ttp://www.din.or.jp/~ohzaki/perl.htm#Character
0328nobodyさん02/04/20 21:14ID:wIgJDzcz
>>327
ジョークのセンスも真似たかったが、
頭が悪いので、今宵そこまで気が回らぬ

ありがたく承ったぞ。

my $str = "書き込みえらー出そうだね。";
print $str =~ /\xA4[\xA1-\xF3]/g;
0329nobodyさん02/04/24 00:23ID:IbG6vdJY
perlで半角英数字を"a"という文字に変更する書き方を教えてください。
0330nobodyさん02/04/24 00:36ID:aRrtBceI
>>329
$val = $text
$val =~ s/[A-Za-z0-9]/a/g;
0331nobodyさん02/04/24 00:42ID:IbG6vdJY
ありがとうございます。
0332nobodyさん02/04/24 00:44ID:IbG6vdJY
あっ間違えた。半角英数字以外の文字を1文字ずつaにする方法が知りたかったのだ。
$val=~s/[^A-Za-z0-9]/a/g;でいいのでしょうか。
0333nobodyさん02/04/24 00:49ID:aRrtBceI
OKです。
また、エスケープシーケンス使ってこんなのでもOK。
$val=~s/\W/a/g;
0334nobodyさん02/04/24 00:57ID:IbG6vdJY
1文字ずつ変更するものなのかわからなかったもので。ありがとうございます。
0335nobodyさん02/04/24 01:00ID:???
>>333
\Wだと'_'が変換されない罠
0336nobodyさん02/04/24 01:11ID:???
>>335
すまった!(ワラ
0337nobodyさん02/04/24 02:20ID:gV/ea89m
>>332
これってタブとか文字コードやスペースも変換してくれるのでしょうか。
0338nobodyさん02/04/24 02:30ID:???
(´-`).。oO(文字コードの変換ってなんだろう…)
0339nobodyさん02/04/24 04:44ID:???
絵文字のように文字にならないコードのことと思われ
0340 02/04/24 07:09ID:AP/UWkPc
>>337
&hearts;のような実体参照はaにはならず&aaaaaa;になる。
0341 02/04/24 07:10ID:AP/UWkPc
>>337
&hearts;のような実体参照はaにはならずaheartsaになる。
0342 02/04/24 07:11ID:AP/UWkPc
340は間違えた。
0343nobodyさん02/04/24 15:36ID:???
>>340
実体参照でなく絵文字のようなコードは。
CGIぽん
ttp://specters.net/cgipon/labo/it_emoji.html
0344nobodyさん02/04/24 18:26ID:???
部分文字列としてabとbaを同じ数だけ含むような文字列にマッチする正規表現を教えてください。
0345nobodyさん02/04/24 20:08ID:???
「abとbaを同じ数だけ含むような文字列」とやらを教えてください。
0346nobodyさん02/04/25 06:16ID:???
abaとかabaaaabaaです。
0347nobodyさん02/04/25 07:50ID:???
>>346
my $str = 'abaaaabaa';
my (@ab, @ba);
print 'Matched' if (@ab = $str =~ /ab/g) == (@ba = $str =~ /ba/g);

"aba" みたいにマッチ箇所がオーバーラップしていても良いのなら上のやつで.
正規表現一発でいけるのなら漏れも知りたい.

マッチ箇所のオーバーラップが許されていなくて
"ababab" でも "ab a ba b" と分けられるからマッチだ! とかいう難問かとオモタヨ…
0348nobodyさん02/05/02 00:59ID:ErHIGJRy
>>347
> マッチ箇所のオーバーラップが許されていなくて
> "ababab" でも "ab a ba b" と分けられるからマッチだ! とかいう難問かとオモタヨ…

これって出来るの?
0349nobodyさん02/05/03 01:20ID:???
オレにはパターンマッチ・置換を正規表現でできなかったためしがない。
なんでもオレに聞きやがれ。適切な答えをはじき出してオマエに叩きつけて
やるゼ!

きっ、きまったぁ!
0350nobodyさん02/05/03 11:30ID:6+RS1vf9
ばーkぁいl7いl7いl7いl7いl7い
l7いl7いl7いl7いl7いl7いl7kyそpr
@いhw45えsっyyyyyyyyybhんtrs5じゅhじゅ
hじゅhじゅhじゅhじゅhじゅhじゅhじゅhじゅhじゅhじゅh
ゅhじゅhじゅy234rthじゅrthjrstw45hjhjt5
hjt5346
コテハンは死ね!
0351nobodyさん02/05/09 06:02ID:???
すいません、perl で URL の表記を区切って使用したいのですが、
正規表現の理解が浅く、まだ上手くできません。
存在しないサービスや、表記の規則違反はあとで考えるとして、
どのようなパターンで取り出せば良いものでしょうか。

my $rule = '([a-z]+)://([^:/@]*):?([^@:/]*)@?([\d\w._\-]*):?(\d*)([\d\w._/\-]*)\??([\w\d%=+&]*)';
my $url = 'http://user:[email protected]:21/path/?key=value&query';
my ($service, $user, $pass, $host, $port, $path, $query) = $url =~ m/$rule/;

このままですと http://host.net/path/ のような user@pass が
全く省かれた場合に、前に詰まってしまいました。
読み難い上に無駄な指定も多いのですが、何方かご教授願えませんか?
0352nobodyさん02/05/09 20:53ID:???
>>351
他にも問題は山積しているんだけど、取り敢えず ? がどこまで有効なのか考えよう。
(〜)@? → (〜@)? とか。
0353nobodyさん02/05/09 21:37ID:???
>>352
有難う御座います。() の後に ? を置けるのは初めて知りました。
マッチするのは直前の単なる一文字ではなく、一パターンだったのですか。

# http URL の正規表現
# http://www.din.or.jp/~ohzaki/perl.htm#httpURL
ココを参考にしながら精進する事にします。
035453102/05/09 21:57ID:???
御陰様でなんとか出来たような感じです。

(?:([a-z]+)://)?       # Service
(?:([^:/@]*)?:?([^@:/]*)?@)? # ID:PASS
([\d\w._\-]*)         # Host
(?::(\d*))?          # Port
(?:([\d\w~._/%\-]*))?     # Path
(?:\??([\w\d%=+&]*))?     # Query

よく考えると皆さんが正規表現に凝ってらっしゃるのは
エラー (汚染) チェックも兼ね備えているからなんですかね。
私も早く安心して任せられるようになりたいです。
0355nobodyさん02/05/09 22:31ID:???
>>354
頑張ってなー。あと、質問する時はなるべくageてなー。
0356351=353=35402/05/09 23:50ID:???
>>355 ハイです (*´ー`*)
035735102/05/10 23:19ID:???
>>354 自己レスですが、\w を [A-Za-z] だと勘違いしてました (汗
0358nobodyさん02/05/15 23:13ID:???
特定の文字列以降の文字を消すのはどうやるのですか?
厨質問ですみませんです。
0359nobodyさん02/05/16 00:44ID:???
>>358
$_ = 'Look-behindで文章中の特定文字列以降の文字を消すよ.';
s/(?<=特定文字列).*//s;

Perl 5.005 以前のバージョンならこっちで.
s/(特定文字列).*/$1/s;
0360nobodyさん02/05/16 01:26ID:???
>>359
どうも、ありがとうございます。
やってみます。
0361nobodyさん02/05/26 06:41ID:65ctyZPu
タグの中からパスを取り出そうとしているのですが
$str = "<a href=\"./hoge/hoge.html\"><img src=\"./hoge.jpg\"></a>";
if($str =~ /<a href="(.*?\.jpg)">/i){print $1."\n";}
とすると、何も出力されないはずなのに
./hoge/hoge.html"><img src="./hoge.jpg
と出力されてしまいます。どうすればよいのでしょうか?
0362nobodyさん02/05/26 07:59ID:???
>何も出力されないはずなのに
いや、.*?なら出力されると思うよ。(<a href="になってるのは間違い?)
./hoge.jpgが欲しいなら /<img src="([^"]+\.jpg)">/に変えてみれば?
0363nobodyさん02/05/26 08:22ID:65ctyZPu
>>362
いや、./hoge.jpgが欲しいんじゃなくて
aタグの""の中身にはマッチしないから何も出力しないようにしたいのですが。
(もちろんhtmlとかにすると出力されるようにはしたい)
0364nobodyさん02/05/26 23:36ID:???
>>361
/<a href="([^"'>]*?\.jpg)">/i

[^]の使い方でも勉強すればぁ?(゚Д゚)
0365nobodyさん02/05/27 00:50ID:???
HTML::LinkExtorを使うのが正しいかと。
0366nobodyさん02/05/27 02:58ID:???
>>364
すいません。>>362の解答を応用してなんとかできした。
■ このスレッドは過去ログ倉庫に格納されています