正規表現道場@2ch Part2
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
02/11/24 22:57ID:LrbVcl3Yこのスレは有用そうな正規表現を紹介したり、どう表現したらいいかわからないときに
質問をしたりするためのスレッドです。
質問するときは使用言語や得たい結果をなるべく詳しく書きましょう。
リンクなどは>>2-5のあたりに。
005250
02/12/09 12:07ID:???^\d+(?:\.\d+)?$
とすると希望の動作しました!ありがとうございます。
005350
02/12/09 12:31ID:N8zphpYN^\d+(?:\.\d+)?$
これを丸々否定したいのですが、
^[^\d+(?:\.\d+)?]$
だとダメでした。
どのようにすれば良いでしょうか…。何度もスイマセン。
何がやりたいかというと、とあるcgiでの入力チェックを行う際に
「有効書式設定」「無効書式設定」というのがあります。
そこにフォームからの入力チェックを正規表現で設定できるのですが、
「有効書式設定」に先ほどの正規表現を入力すると
必ず入力しなくてはならなくなりました。
ですので「無効書式設定」に先ほどの正規表現を
丸々否定したものをすれば、必ず入力しなくても良くなるのでは
と思って質問させていただいてます。
005550
02/12/09 17:05ID:N8zphpYN許可したくないものまで許可できてしまいました…。
ですので、「整数と小数、または、0文字を許可」という条件を
「有効書式設定」の所に設定し直そうと思います。
整数と小数の部分は
^\d+(?:\.\d+)?$
でいけてるのですが「または、0文字を許可」の部分を
↑にどのように付け加えればよいのかわかりません。。
すいませんがよろしくお願いします。
0056Name_Not_Found
02/12/09 17:29ID:Pf18ytiH0文字を許可を入れる場合の定石は、
処理ループの(ループだよね?)最初で /^$/ 等でマッチさせる。
一つの正規表現でやるよか速くなる可能性高いからそっちも考えて。
"または" がきたら、普通に if とかの使用も考えること。
005755
02/12/09 17:40ID:N8zphpYN今回、cgiそのものを書いているのではなく
cgiを設定する画面が存在して、その「有効書式設定」部分に
正規表現を書けば、自動的に入力チェックを行ってくれるというものです。
┌―――――――┐
有効書式設定:| |
└―――――――┘
cgiのこのテキストボックスに書くって感じです。
なので、一つの正規表現で解決させたいです。。
0058Name_Not_Found
02/12/09 17:48ID:???なるほど。でしたら、
^(?:\d+(?:\.\d+)?)?$
で。
.0123 とかを許可するんだったら
^(?:\d+)?(?:\.\d+)?$
で。
006036
02/12/09 18:50ID:???>>37,42,45
ありがとうございました、無事変換できました。
つまり、?が要らなかったんですね。
<code>あああ</code>ほげ<code>ほげ</code>ふがふが</code>
つまり、最初と最後の<code></code>のみを変換して、
間に入っているタグは無効にしたかったんです。
かなり悩んでいたので、助かりました。感謝です!
0061nobodyさん
02/12/09 23:44ID:???0063nobodyさん
02/12/10 06:27ID:QO7zNhpw何に対してマッチしたかがわかりません。
例えば
if($ref=~ /ああ/ || $ref=~ /いい/ || $ref=~ /うう/ || $ref=~ /ええ/){
$ref=さっきマッチした語句 , "おお";
}
みたいな処理をする場合、さっきマッチした語句を調べるにはどうしたらいいのでしょうか?
$_ とか$1を当てはめても上手くいかないんですが。
お願いします。
006463
02/12/10 06:34ID:???0065nobodyさん
02/12/10 07:37ID:???みたいなフォーマットの文を
この例では「2ちゃんねる」に当たる部分だけ抜き出したいので
$text=2ちゃんねる&hc=0&hs=0;
$text =~ /format(.*)\&(.*)/:
$hensu=$1;
みたいに書くと、$hensuの中身が
「2ちゃんねる&hc=0」という風に
一番最後にある「&」で区切られてしまいます。
最初に出くわした「&」で区切りたい、という時にはどうしたらいいんでしょうか?
0066nobodyさん
02/12/10 07:51ID:???[→[
]→]
と言う風に置き換えをしたいのですが、下記のようにすると
$msg =~ s/\Q[\E/?/g;
$msg =~ s/\Q]\E/?/g;
ー の文字コードが81 5Bで、 [ の文字コードが5Bなので
ー が文字化けをしてしまいます。
文字コードはShift_JISです。どういう風にすれば文字化けを回避できるでしょうか?
0067Name_Not_Found
02/12/10 10:17ID:SHy7dsCG.* とか .+ は最も長くマッチしようとします。
.*& ってやると後ろの & まで見ちゃうわけですね。
そういう場合は .*? みたいに、後ろに ? を付けると
なるべく短かくマッチしようとするようになります。
>>66
前の文字が Shift JIS の 1byte目じゃなければ置換、ってすればいいのかな。
s/(?:(?:^|[^1byte目の範囲を書いてね])\[)/?/g;
試してないからわからないけど、これでどうでしょう?
0068Name_Not_Found
02/12/10 10:18ID:???括弧余計すぎた。
そと側の (?: .. ) はいらないわな…
0070Name_Not_Found
02/12/10 11:42ID:SHy7dsCGただ、.*? は遅くなることがあるから、
この場合は [^&]*& の方が望ましいです。
0071nobodyさん
02/12/10 12:21ID:???速いのってどんなやつ?
kentでは
$test =~ s/([^=^\"]|^)(https?\:[\w\.\~\-\/\?\&\=\@\;\#\:\%]+)/$1<a href=\"$2\" target=\"_top\">$2<\/a>/g;
ってやってるみたいだけど これ遅くない?
007472
02/12/10 12:44ID:???それを削ってこんな感じ。
$test =~ s/(https?\:\/\/[a-zA-Z\.\~\-\/\?\&\=\@\;\#\:\%_!*'()]+)/<a href=\"$1\">$1<\/a>/g;
ちなみに、[]内はURI使える文字だけど、kentのは不足している。
動作確認していないので、フォローよろしく。
007572
02/12/10 12:59ID:???$test =~ s/(https?\:\/\/[-a-zA-Z0-9.~\/?&=\@;#:%_!*'()+\$,]+)/<a href=\"$1\">$1<\/a>/g;
0076nobodyさん
02/12/10 14:39ID:???ではダメ?
007776
02/12/10 14:41ID:???007876
02/12/10 14:44ID:???かな?
007976
02/12/10 14:45ID:???だ・・・鬱
0084nobodyさん
02/12/10 16:45ID:???0085Name_Not_Found
02/12/10 17:02ID:???それよか、IRIなんてのがひかえてますよ。
008666
02/12/10 22:19ID:???ありがとうございます。1バイト目の文字は
\x81-\x9F\xE0-\xFC
ですが、その通りにしてもなぜか>が消えてしまうようです???
例えば<BR>の次に[が来ていると、
<br? こうなってしまいます。
もしかして、s/(?:^|[^1byte目の範囲を書いてね])\[/?/g;
この場合、Shift_JISの1バイト目の文字以外が来たら、
その文字と[を?の文字に変換してしまうのではないでしょうか?
見当違いならすみません・・・
0087nobodyさん
02/12/10 22:27ID:???これだと、上手くいったような気がします。
>>67さん、ありがとうございました!
008866
02/12/10 22:29ID:???0089nobodyさん
02/12/10 23:02ID:???$hogeが'bookmark'だとちゃんと弾くけどcacheが入ってる場合に弾いてくれない。
http://www.din.or.jp/~ohzaki/regex.htm#Without
ここのやつの意味を勘違いしてるのかなぁ。
0090nobodyさん
02/12/10 23:22ID:???0092Name_Not_Found
02/12/11 01:43ID:61zg/eqGああああ、ごめんなさい。
たしかに、1byte目が消えちゃいますね。
()で$1に保存するか、look-behind 正規表現を使えばいいのかな。
(?=...)の look-ahead はそういうケースでは駄目なはず。
$1 の方は、
s/(^|[^範囲])\]/$1[/g
でいいはず。
look-behind は
s/(?<![範囲])\]/$1'amp;#91;/g
かな。こっちは Perl のバージョンが古いと使えない。5.6 あたりなら大丈夫。
0094
02/12/11 17:44ID:YVHUV6QH>>94という具合に
ページ内にリンク先がある場合に限ってリンクを張りたいのですが
どうしたらいいでしょうか。
【悪い例】
$foo=">>1 hogehoge\n>>2 hogehoge\n"; #置換対象文字列
$num="94"; #最新レスの番号
$max="100" ; #1ページあたりの表示件数
if(($num>$2)&&($2>$num-$max)){
$foo =~ s/(>>)([1-9][0-9]*)/<a href="#$2">$1$2<\/a>/g;
}
置換以前の$2では当然うまくいきませんです。
しかも、置換対象が2つ以上ある場合はどうしたらいいのでしょうか。
009594
02/12/11 17:49ID:YVHUV6QHでございます。
0096Name_Not_Found
02/12/11 18:06ID:7uJNDqfwmy $max =100; # これは range で
my $num =94; # こっちが max の方がいいような気もするけど。
my $foo=<<EOB;
>>1 hogehoge
>>2 hogehoge
EOB
my ( $high, $low ) =( $num, $num - $max );
$foo =~s/(?:>>)(\d+)/
$low <= $value and $value <= $high ? qq(<a href="#$1">>>$1</a>)
: qq(>>$1) /sge;
009796
02/12/11 18:08ID:???$value ってなんじゃ…
$1 ね。
009894
02/12/11 18:11ID:YVHUV6QH009994
02/12/11 18:49ID:YVHUV6QH恐れながら、$1は、>>にマッチするのではないですか?
すみません教えてください。
010096
02/12/11 20:29ID:7uJNDqfw(?:..) は $1..9 に値を保存しません。
なので $1 で問題ないです。
動かなかった理由は / がクォートされてなかったのと
置換文字列を一行に纒めなてかったからのようでした。
なので、s/// の替りに s{}{} を使っときます。
my $max =100; # これは range で
my $num =94; # こっちが max の方がいいような気もするけど。
my $foo=<<EOB;
>>1 hogehoge
>>2 hogehoge
EOB
my ( $high, $low ) =( $num, $num - $max );
$foo =~s{(?:>>)(\d+)}{
$low <= $1 and $1 <= $high ? qq(<a href="#$1">>>$1</a>)
: qq(>>$1) }sge;
010196
02/12/11 20:31ID:7uJNDqfw意味無いんで外しといてください。
010294
02/12/12 00:14ID:pDUwoT6Y0103nobodyさん
02/12/24 22:43ID:???0104名無しさん
03/01/03 00:29ID:yu7P73hS最短マッチが、いろいろ読んだけどわかりません。phpです。
/* hoge */ hogehoge /* hoge */ の /* */
で囲んだ部分だけ灰色にしたいんです。
ereg_replace("(/\*.+\*/)","<font color=\"gray\">\\1</font>");
こうすると 最初と最後の/* */にマッチしてしまいます。
たぶん、最長マッチだからです。
最短マッチにするには?をつけろと書いてあるけど、どこにつけるかわかりません。
(/\*.+\*/){1,}? こうするとなにも出てきません。
なんか基本的なことがわかってないです。
0105nobodyさん
03/01/03 00:46ID:nupLg+Ov0106104
03/01/03 01:09ID:yu7P73hS0107104
03/01/03 01:23ID:yu7P73hS教えてください・・・
0108nobodyさん
03/01/03 01:27ID:nupLg+Ovもしかしたらereg()で最短一致は使えないのかも。
preg_replaceでなら上手くいくかも。
0109104
03/01/03 01:40ID:yu7P73hSでもpregでもできません・・(;_;)
というか、なにも表示されないというのがアヤシイです。。
0110nobodyさん
03/01/03 01:41ID:???0111nobodyさん
03/01/03 17:38ID:???このように書いてもソが脳内通りに取得出来ないんですが
どうすればいいんでしょうか?
0112nobodyさん
03/01/03 21:33ID:nupLg+Ov0114山崎渉
03/01/15 13:36ID:???0115nobodyさん
03/01/18 13:42ID:???URLの抽出前に<>"を文字参照に置き換えると、
URLの抽出を行うと、http://www.yahoo.co.jp">Yahoo</a>
とかもa>までURL扱いになってしまい、困っています。
$msg=~s/(http|ftp|mailto)\:([\w.\@~\/\-\?&=;%#]+)/\<a href=\"$1:$2\">$1:$2<\/a>/g;
URL抽出部分はこんな感じです。
0116nobodyさん
03/01/18 13:45ID:hA2YqZMs0118115
03/01/18 18:54ID:???>じゃあ、抽出後に<>を置き換える。
抽出後に<>を置き換えると、
<aまで<aに置き換わってしまうので・・・
>まとめて括弧でくくれば
そうですね。
で、一旦[link]http://www.yahoo.co.jp[/link]に置き換えてから、
<>を置き換えて、[link]...[/link]を置き換えるというもの考えたんですが、
それだと
=~/\[link\](.*)\[\/link\]/\<a href=\"$1\">$1\<\/a\>/g;
等としても、最初の[link]から最後の[/link]までが置き換わってしまって、
2つlinkが続く場合等に予期しない結果になってしまいます。
0120115
03/01/18 19:23ID:hA2YqZMs表示時にタグ付けすると解決する?
0122115
03/01/18 19:33ID:???<a href="http://www.yahoo.co.jp/&quot;>Yahoo</>
とかになるわけで・・・
0123nobodyさん
03/01/18 19:38ID:???なんでやねん。
データ:
http://www.2ch.netって死ぬほどおもしれー!
表示:
<a href="http://www.2ch.net">http://www.2ch.net</a>って死ぬほどおもしれー!
0124115
03/01/18 19:47ID:???<a href="http://www.yahoo.co.jp/">Yahoo!</a>
と投稿した場合。
char str[]="http://www.yahoo.co.jp/";
等でも同じ。(この場合はco.jpの後の"もリンク扱いされてしまう)
0127nobodyさん
03/01/20 08:07ID:vz/F/uwh一番エレガントな書き方ってどういうのですか?あと
$url = 'http://www.2ch.net/';
$url =~ s/2ch/1ch/;
と書いた場合になんで$url のなかの"/"をエスケープしなくても
エラーにならないんでしょうか?
0129nobodyさん
03/01/20 08:09ID:???http\/\/:(www\.)?2ch\.net\/
0131nobodyさん
03/01/20 19:22ID:gSzazTgePerlだと、こう書く。
m#^http//:(?:www\.)?2ch\.net/$#
完全一致だよね。知らないけど。
あと、DNSは大文字小文字を区別しないから、この書き方は間違ってる。
今の場合は、単に正規表現を聞いてるんだから、/をエスケープする必要は無いし、
それに、Perlで使うときも、いちいち/をエスケープするのは、エレガントじゃない。
0132nobodyさん
03/01/20 20:43ID:vz/F/uwhでも、なんで
s/http://www\.2ch\.net/http://www\.1ch\.net/;
がエラーで
$url = 'http://www\.2ch\.net/';
$b = 'http://www\.1ch\.net/';
$url =~ s/$url/$b/;
がokなんでしょうか?
そのへんの理屈がよく分かりません
0133nobodyさん
03/01/20 21:52ID:gSzazTgeから、インタプリタはs/ / /を認識できる。
0134nobodyさん
03/01/20 22:08ID:???s///による置換を行う前に、s///の構文チェックをしているからでしょう多分きっと。
s/http://www\.2ch\.net/http://www\.1ch\.net/;
sの次に/があるので/を区切りとした構文としてチェックしてみる。
3つ目の/以降はスイッチ部。
wwwというスイッチは存在しないので、エラー出力
(Bareword found where operator expected, near "s/http://www")
s/$url/$b/;
構文としてはs///という形になるのでOKなので、
次に、正規表現の文字列となる$urlを正規表現のスタック?に展開して積み込み、
同じく$bを展開部用のスタックに積み込んでいるのではなかろうか。
あくまでも想像。
0135nobodyさん
03/01/22 11:39ID:Lm4zDQtU/(^.*key.*$)/$1/
じゃダメポ。
というのも、とあるテキスト書換えソフトでgrep出来たらいいなと。
0137nobodyさん
03/01/22 11:44ID:???foreach(@hoge)
{
if(/^.*key.*$/)
{
push(@a,$_);
}
}
で、良いじゃん。正規表現が合ってるかはは知らんけれど
0138nobodyさん
03/01/22 12:04ID:Lm4zDQtUgrepが使えたらこんな事はしないかと。
>>137
if等は使えないんですよ。
つまりエディタの検索、置換えに指定する事でgrepするようなものです。
0140nobodyさん
03/01/22 14:10ID:Lm4zDQtU例えですけど、メモ帳の置換えでif使えますか?
マクロじゃないですので使えないです。
0144nobodyさん
03/01/22 15:59ID:???0145nobodyさん
03/01/22 16:47ID:Lm4zDQtU何か大きく勘違いなされてるようで。
とにかく、1行(s/find/rep/)の構文だけでgrepと同じ事を出来ないかと言う事です。
スクリプトを組めるなら最初からそうしますが
制約上そのような事ができません。
0147nobodyさん
03/01/22 17:30ID:Lm4zDQtUどういう事でしょうか?
0148nobodyさん
03/01/22 17:36ID:???はじめから落ち着いて、
・一体どんなアプリケーションを作っているのか。
・一体そのアプリケーションのどの処理で悩んでいるのか。
・ifが使えない制限とは?
位は書いてくれい。
0149nobodyさん
03/01/22 17:56ID:Lm4zDQtU・使ってるソフト。
よくあるファイル一括書換えソフト。
・やりたい事
メモ帳の置換え(CTRL+H)のような感じで
検索する文字と置換えする文字を指定する事で
ファイルの内容を一気に高速で書き換えられる。
検索文字列及び置換え文字列はBREGEXP.DLLを使う事で
Perlと同等の置換えが指定できる。
その検索文字列と置換え文字列の指定方法。
・IFが使えない理由。
メモ帳のように検索文字と置換え文字を指定する事しか出来ない為。
ソフトを作ってる訳ではなく使っているだけ。
です。以上で分かって頂けるでしょうか?
0151nobodyさん
03/01/22 18:06ID:Lm4zDQtU何故無理と言い切れるのでしょうか?
0152nobodyさん
03/01/22 18:18ID:???■ このスレッドは過去ログ倉庫に格納されています