トップページ⇒php
981コメント340KB

正規表現道場

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2007/01/11(木) 02:40:43ID:uW7xEbZY
【正規表現道場の掟】

・言語不問

・質問も大歓迎。使用言語を書くのを忘れずに。

正規表現と関係ない話・質問は他スレへどうぞ。
0002nobodyさん2007/01/11(木) 03:10:51ID:???
http://pc10.2ch.net/test/read.cgi/tech/1156413899/

終了
000312007/01/15(月) 00:57:08ID:/DToo9Jn
勝手に終了すんなデブ
ここはここでやればいい
再開あげ
0004nobodyさん2007/01/15(月) 20:06:50ID:???
>>2は道場破り?
0005nobodyさん2007/01/15(月) 22:01:26ID:???
一年ぶりの復活をしたなら過去スレくらい書こうぜ('A`)

過去スレ
正規表現道場@2ch
 http://pc.2ch.net/test/read.cgi/php/996105815/
正規表現道場@2ch Part2
 http://pc5.2ch.net/test/read.cgi/php/1038146241/
正規表現道場@2ch Part3 s/煽り|荒らし/あぼーん/g
 http://pc5.2ch.net/test/read.cgi/php/1069245758/
正規表現道場@2ch Part4
 http://pc8.2ch.net/test/read.cgi/php/1105930285/


過去スレのテンプレにあった参考サイトたち
Perlメモ
 http://www.din.or.jp/~ohzaki/perl.htm
正規表現メモ
 http://www.kt.rim.or.jp/~kbk/regex/regex.html
Regex::Diagram.pm
 http://www.cc.rim.or.jp/~midorin/mad-p/RegexDiagram.html
正規表現
 http://www.cc.rim.or.jp/~midorin/mad-p/perl/benkyou/PRC2kRegex/
UNIX正規表現入門
 http://web.archive.org/web/20021219021503/http://www01.u-page.so-net.ne.jp/jc4/hiroyuki/rex_index.html
Regular Expression(Riue ちゃんの正規表現講座)
 http://www.sixnine.net/regexp/

ほとんどは↓のリンク集にまとまっています。
正規表現/文字コード最新リンク2005
 http://www2.famille.ne.jp/~akio1998/l_grep.html
0006nobodyさん2007/01/16(火) 02:57:15ID:???
>>5
ご苦労様です
0007()と(?:)の違い2007/01/21(日) 14:23:29ID:HARdTCVv
対象文字列 //abca
正規表現 ^(/([a-z]*))*$ → マッチ
正規表現 ^(/(?:[a-z]*))*$ → マッチしない

後方参照を許す括弧かそうでないかで結果が違うのはなぜでしょうか?
処理系は PHP 5.2.0-8、OS は Debian GNU/Linux etch
使用した関数は preg_match() です。

具体的には
preg_match('"^(/(?:[a-z]*))*$"', "//abca", &$m);
var_dump($m);
とすると $m[0] が空文字列になります。
すなわちマッチしません。
0008nobodyさん2007/01/21(日) 15:16:09ID:???
>>7
preg_matchに与える正規表現は/で括る必要があるけど、原因はそれじゃない?
正規表現reをpreg_matchに与えるときは
preg_match("/re/", $baka);
とかやるんだけども。
0009()と(?:)の違い2007/01/21(日) 15:25:20ID:HARdTCVv
>>8
いちおう '@^(/(?:[a-z]*))*$@' などとして区切り文字を
@ にするなど気をつけているのですが・・・
()と(?:)により挙動が違うというのが解せません・・・
もう少し実験してみます。ereg 系で試すとまた
結果が違ってくるかも知れないので。
0010nobodyさん2007/01/21(日) 20:27:33ID:???
これは…PCREのバグを踏んじゃった可能性が結構高そうな…
echo preg_match('{^(?:/(?:[a-z]*))*$}', "//abca");
=> 0

Perl互換正規表現と言うくらいなのでPerlとの比較をしてみても勿論このとおり
$ perl -e 'print scalar "//abca" =~ m{^(?:/(?:[a-z]*))*$};'
=> 1

後で念のためPCRE直接叩いてみよう
0011()と(?:)の違い2007/01/21(日) 21:20:40ID:HARdTCVv
>>10
ふぅむ、バグの可能性もあるんですか〜
//abca じゃなくて /abca/abca とかならマッチするんですよね。
実はパスをディレクトリに分解しようとおもいまして、
その途中に // が入っているようなケースで挙動がおかしいので調べてました。
//abcde は / と /abcde に分解したかったんです。
0012102007/01/21(日) 23:05:47ID:???
ふう、PCRE付属のpcretestでバージョン別検証。
[PCRE version 6.6 06-Feb-2006]
re> /^(?:a(?:b*))*$/
data> aa
0: aa

[PCRE version 6.7 04-Jul-2006]
re> /^(?:a(?:b*))*$/
data> aa
No match

[PCRE version 7.0 18-Dec-2006]
re> /^(?:a(?:b*))*$/
data> aa
0: aa

ver6.7のみ上手くマッチしないと言う結果になった。
changelogの7.0をみてもそれっぽいのが見つけられないけれど、38辺りかなぁ…

ちなみにPHPで使ってるPCREのバージョンは、
phpinfoのpcreのPCRE Library Versionで確認できる
0013nobodyさん2007/01/22(月) 00:49:01ID:???
ちょっといいかな。
>>12 の結果に疑問はないのだけど、

>>7 の
> preg_match('"^(/(?:[a-z]*))*$"', "//abca", &$m);
は空文字列にマッチで正解じゃないの?
だって、対象文字列には // と行頭に二つスラッシュが並んでいるけど、
正規表現は ^/ と一個しかないよ?

後ろに $ が置かれちゃってるから、
//hogehoge というパターンには空以外マッチしようがないと思うんだけど
俺、何か勘違いしてる?
0014nobodyさん2007/01/22(月) 01:56:13ID:???
>>13
多分、中のアルファベットに対する量指定子を考慮に入れてないんでないかい?
^ # 文字列の最初
 (
  /(?:[a-z]*) # /の後に[a-z]が0文字以上
 )*       # の0回以上繰り返し
$ # 文字列(行)の最後

//abcaは、<スラッシュ、[a-z]が"0文字"、スラッシュ、[a-z]が4文字>となってマッチしなければならない。はず。

>>11
その目的だとpreg_matchじゃ駄目だと思う。
一個目のキャプチャが繰り返しを全て記録することを期待したんだと思うが、毎回上書きされてしまう。
パス文字列が妥当なものかをマッチングで検証するためにpreg_matchを用いて、
実際の切り分けはexplode等を使ったほうがいいんじゃないかな。スレ違いになるが。
マッチングで切り分けるとするならpreg_match_allを用いて
preg_match_all('{\G/[a-z]*}', "//abca", $m)
といった感じか
0015()と(?:)の違い2007/01/22(月) 04:08:40ID:???
>>12
ビンゴのようです。
手元の二つのLinuxマシンで試してみました。

preg_match('"^(/(?:[a-z]*))*$"', "//abca", &$m);

Debian GNU/Linux etch
PHP 5.2.0-8 PCRE 6.7 04-Jul-2006
マッチしない。

Fedora Core 4
PHP 5.1.6 PCRE 6.3 15-Aug-2005
マッチする。
0016()と(?:)の違い2007/01/22(月) 07:00:19ID:???
>>12
TurboLinux Server 8.0 (Viper) での挙動も調べてみました。

preg_match('"^(/(?:[a-z]*))*$"', "//abca", &$m);
preg_match('"^(/(?:[a-z]*))*$"', "/a/abca", &$m);
いずれもマッチします。
PHP 4.2.3 PCRE 3.4 22-Aug-2000 です。

やはり Debian GNU/Linux etch の PHP5 5.2.0-8 だけが
PCRE 6.7 04-Jul-2006 を使っていて挙動が変みたいなんで、
Debian GNU/Linux の BTS (バグ報告)に挙げようとおもうんですが、
>>12 の結果も引用させてもらって構いませんでしょうか?
0017132007/01/22(月) 11:21:28ID:???
>>14
ありがとう。指摘通り誤読していた。
拡張表記をみてわかったよ。

やっぱLarryは偉いな。

ところでかっこの内と外で繰り返し指定が
連続するパターンは組み合わせの爆発が
怖くて自分はできるなら使わないように
しているんだけど、みんなはそんなこと
気にしない?
0018()と(?:)の違い2007/01/22(月) 12:31:13ID:???
>>17
DFAだからとりあえずえらいことにならないうちに停止するだろう、
とか自分では思い込んでるんですが、NFAなら延々とバックトラック
しながらはまり込むとかあるんですかね。
0019102007/01/22(月) 21:04:29ID:???
>>16
どうぞお使いください。
でも、phpのソースにpcreが同梱されてるようだけれど報告先ディストリでいいのかな…
0020()と(?:)の違い2007/01/22(月) 21:51:33ID:???
>>19
ありがとうございます。
むしろ PHP のバージョンごとあげてもらえればと。
って、最新バージョンのソースに入ってるのか orz
ちょっと PHP のソース眺めながら思案してみます。
0021202007/01/23(火) 00:05:58ID:???
>>19
I've reported this issue to PHP bug report.
http://bugs.php.net/bug.php?id=40195
Complete report and examination results are in
http://geeklog.windy.cx/article.php/20070122224722545
I'm in my Linux box without Japanese environment :-p
0022202007/01/23(火) 07:47:35ID:???
Nuno Lopes さんからリプライがあり、修正対象となりました。

[22 Jan 9:43pm UTC] [email protected]
I confirm this is a bug in pcre. so let's ask Andrei to
upgrade PCRE to version 7, maybe for PHP 5.2.2
(assign back to me if you want me to do it).
0023nobodyさん2007/01/23(火) 17:36:48ID:???
>>21-22
これは模範としたいバグ報告。乙です。
0024nobodyさん2007/01/23(火) 21:15:28ID:EGIjqz4P
perl質問厨よろしくです。
@array = split(/(hoge(.))\2/, $line);
この2番目の括弧だけ@arrayに含めないことはできますか?
'----hoge11-----'
↓
('----', 'hoge1', '-----')
という風に取り出したいのです。
0025nobodyさん2007/01/23(火) 22:31:38ID:???
すいません。別の方法で解決しました。
0026nobodyさん2007/02/01(木) 17:35:44ID:???
http://pc10.2ch.net/test/read.cgi/tech/1156413899/

終了
0027202007/02/14(水) 08:22:19ID:???
[9 Feb 7:58pm UTC] [email protected]
bundled pcre upgrade to version 7.0.
0028nobodyさん2007/02/17(土) 11:34:20ID:???
PHPで正規表現
http://www.pahoo.org/e-soul/webtech/php05/
0029nobodyさん2007/02/18(日) 02:46:46ID:???
マルチで宣伝か?
0030nobodyさん2007/02/20(火) 02:12:09ID:???
質問よろしくお願いします

ABCと続く場合を除くABという文字列を指定したい場合は
どのように書いたらよいでしょうか・・・
0031nobodyさん2007/02/20(火) 02:21:35ID:???
正規表現ってどんなメリットあるの?
覚えなくても良いんでしょ?
よく、書く行数が減る⇒デバッグの時に楽って言うけど、
ロジック設計を完璧にするほうが大事じゃないかなーなどと思ってしまいます(ドシロウトですが)
そんなのとうに完璧って人がチャレンジすることなんですかねー
0032nobodyさん2007/02/20(火) 02:23:50ID:???
>>30
Rubyでは(おそらくPerlやPHPのpreg_*系でも)
AB(?!C)
0033nobodyさん2007/02/20(火) 02:26:48ID:???
>>31
文字列のパターンを記述するために特化した言語なので、
覚えれば非常に楽ができる。
ロジックで100行とか費やすようなパターンを、
正規表現では1行で表すことも可能(かもしれない)。

覚えなくてもいいが、覚えた方がはるかに楽ができるよ。
0034nobodyさん2007/02/20(火) 07:20:03ID:???
>>31
ロジック組めないやつが楽をするためだよ
文字列から数字の部分だけ抜き出して表示とか正規表現なら簡単に出来るが
使わないでやれとかいわれたら時間がかかる。おまけにバグる。
0035nobodyさん2007/02/20(火) 08:24:42ID:???
数字だけ抜き出すのが何かものすごい魔法のような技術のように思っているらしいw
0036nobodyさん2007/02/20(火) 08:27:41ID:???
あるいは「おれってすげえ気の利いたこと言った?」とか思ってるのかなwww
0037nobodyさん2007/02/20(火) 08:35:59ID:???
【心の】旦那には絶対言えない過去4【奥に】既婚女性板
http://human6.2ch.net/test/read.cgi/ms/1168957905/

7 名前:可愛い奥様[] 投稿日:2007/01/18(木) 03:03:54 ID:iE8GVdnP
援交10回、中絶2回、デリヘル、ソープ1年、整形2か所

12 名前:可愛い奥様[] 投稿日:2007/01/19(金) 22:43:01 ID:s7dkuHKN0
高校生の頃から喫煙。不倫経験あり。
旦那は私にとって7人目の彼氏。(旦那には3人目と嘘ついた)
酒に酔った勢いでワンナイトラブの経験あり。

25 名前:可愛い奥様[] 投稿日:2007/01/26(金) 04:08:25 ID:IfNo5kNWO
中絶4回、イメクラ一年、二重整形、大学中退、性病2回、同棲3回。

45 名前:可愛い奥様[sage] 投稿日:2007/02/04(日) 14:24:40 ID:PBhJa6V+0
自分の預金が旦那の年収の7倍くらいあること。
学生のとき、ちょっとした事業起こして大成功w そのことも話してない。

47 名前:可愛い奥様[] 投稿日:2007/02/04(日) 17:16:59 ID:CaAW9Ko50
うーん。堕胎。母子手帳に記載しないといけないから…そこは糊で貼付けた。
義母にはバレているだろう。でも回数が…1回多いとは…永遠の秘密。

92 名前:可愛い奥様[] 投稿日:2007/02/09(金) 23:46:04 ID:QRXcETQYO
セクキャバでバイト経験あり。援交しまくり時代もあり。ヤッた数は100人くらい。
私バツイチで今の旦那には元夫の浮気が原因で離婚したの。とか言ったけどほんとは逆。
好きな人できて夫捨ててのりかえた。浮気しまくりだった。
すごくいい夫だったのにすごく最低な事したって思う。

106 名前:可愛い奥様[] 投稿日:2007/02/18(日) 09:56:13 ID:wIf/65Md0
半年前、万引きして捕まった事。嘘泣きして逃がしてもらった(^^v
0038nobodyさん2007/02/20(火) 19:16:13ID:W7lgDSO2
/tatakanamk/
と言う文字列があって/から/までの検出をするにはどう書けばよいでしょうか?
/と/も含めて12文字を検出したいのです。
超初歩的ですがよろしくお願いします。
0039nobodyさん2007/02/20(火) 19:38:28ID:???
>>1の
>使用言語を書くのを忘れずに。

くらいは守ってくれ。処理系によって正規表現は千差万別だからな。
0040nobodyさん2007/02/20(火) 19:56:10ID:???
エスパー見習いの漏れが使用言語は Perl と推測。
バックスラッシュを前置してエスケープする。
/\/tatakanamk\//
0041nobodyさん2007/02/20(火) 22:52:27ID:???
>>32
ありがとうございました!
0042nobodyさん2007/02/21(水) 02:10:45ID:???
>>40
m{/tatakanamk/} みたいにやたらとエスケープ連発しないですむ方法を教えろよ… 
0043nobodyさん2007/02/21(水) 03:35:33ID:???
エスケープを知らないのも問題だから両方教えるべきだとおも
0044402007/02/21(水) 10:00:30ID:???
だってもし他の言語だったとしても応用が一番効きそうじゃん。

と言い訳。
0045422007/02/22(木) 01:40:37ID:???
>>43
そりゃ確かにそうだね。
必要のないところまでエスケープしているような正規表現見てると
腹が立ってくるんだよw

>>44
わかった、わかったw
0046nobodyさん2007/03/02(金) 01:04:13ID:???
保守
0047nobodyさん2007/03/10(土) 16:03:45ID:VXyj5Dh3
<?
$str = "/get/data/&country=2&url=http://www.example.com/?url=http://www.example.com";

このデータの中ではじめの url= 以降の文字列を取得するにはどうすればいいのでしょうか?ちなみにurl=以降の文字列にも再度url=が含まれていますが、これを無視してすべて取得したいです。

どうぞよろしくお願いします。
0048nobodyさん2007/03/11(日) 04:44:19ID:???
>>47

url=http://www.example.com/?url=http://www.example.com
がとれりゃあいいのか?

url=.*$

で何か不都合ある?
0049nobodyさん2007/03/12(月) 12:20:51ID:DmSqMrCU
php使ってます。
文字列中の?を抽出するにはどう記述したらいいのでしょう?

¥?

じゃだめなことはわかりましたorz
0050nobodyさん2007/03/12(月) 12:48:47ID:???
バックスラッシュを前に置く。
0051nobodyさん2007/03/12(月) 14:27:04ID:DmSqMrCU
ばっちですた!
0052nobodyさん2007/03/18(日) 21:25:07ID:7HFdTRo7
教えてください。

$in=ユーザーからの入力
$str='abc%ghi';
$str=preg_replace('/(\w+)%(\w+)/',"\1$in\2",$str);

ユーザーからの入力を'def'にしておくと、abcdefghiになります。
ですがユーザーからの入力が'123'の場合、ghiになります。
たぶん、置換後の文字列が「\1123\2」と、繋がって解釈されているからだと思います。
{\1}のように囲むとか、なにか繋がらないように解釈してもらう方法はないですか?

二段階に分けて置換するとかすれば回避できなくはないですがスマートではなさそうなので。
0053522007/03/18(日) 21:25:46ID:???
すいませんphp4です。
0054nobodyさん2007/03/18(日) 22:00:48ID:???
こうしたらこうなるって結果を一行にまとめて
0055nobodyさん2007/03/19(月) 08:43:07ID:???
>>52
"\\1" . $in . "\\2"
"\\1{$in}\\2"

というか普通に\\1と\1を間違えてるだけじゃない?
0056522007/03/20(火) 00:34:39ID:???
>55
>普通に\\1と\1を
すいません間違いでした。(ここに貼ったあと直しましたが動作変わらず。)
そのうえ↓を書いてて解決しました。手間取らせてすいません。


$in='123';
$str=preg_replace('/(abc)%(def)/',"\\1$in\\2",$str); //これが
$str=preg_replace('/(abc)%(def)/',"\\1123\\2",$str); //こうなってしまうので
$str=preg_replace('/(abc)%(def)/',"def",$str); //\\1123はないので消えて\\2だけ置換され
print $str; //defが出力される

と思うので、{$in}でくくっても結果は同じでした。
一番いいのは\\1側を{\\1}くくる方法だと思うのですが。


→phpだと\\1は\$1でもいいので、"\${1}$in\$2"で解決しますた。ほんとすいません。
0057nobodyさん2007/03/23(金) 00:39:31ID:P+rVOV8A
$str = "foo@=barfoo@=bar";
$str = preg_replace('/foo.*(=)bar/', "a\\1b", $str);
を実行した場合の結果をa=ba=bにしたいのですが、
実際はa=bになってしまいます。
どこが間違っているのでしょうか?
0058nobodyさん2007/03/23(金) 02:15:09ID:???
>>57

.* が何にマッチしているのか確かめてみ。
0059572007/03/23(金) 10:16:39ID:P+rVOV8A
>>58
.*を bar と続く文字列以外の任意の文字列に変えればいいというのはわかるのですが、
$str = preg_replace('/foo[^(bar)]*(=)bar/', "a\\2b", $str);
としてもうまくいきません。
エロイ人よろしくお願いします。
0060nobodyさん2007/03/23(金) 10:45:01ID:???
「ある文字列を含まない文字列」の正規表現はめんどいので最短マッチ .*? で。
0061572007/03/23(金) 16:57:03ID:???
>>60
おお!それでできました。
ありがとうございます。
0062nobodyさん2007/03/24(土) 01:11:05ID:???
>>59

foo[^(bar)]*(=)bar

ブラケットの中とかどこでこんな書き方覚えてくるんだよ…
今回の場合、barまで見ないでも = までみりゃあいいんじゃないの?
不用意に最短マッチ使ってるとパフォーマンスで泣くよ?

foo[^=]*=bar を a=b に置換でいいじゃん。
=をキャプチャするのも意図がわからん。
0063nobodyさん2007/03/24(土) 12:15:47ID:yU007f6l
<html>
<head>
<title>テスト</title>
</head>
<body>
<!-- ここから -->
あああああああああああ<br />
あああああああああああ<br />
あああああああああああ<br />
あああああああああああ<br />
あああああああああああ
<!-- ここまで -->
</body>
</html>

このようなhtmlをPHP5のfile_get_contentsで読み込んで
<!-- ここから -->〜<!-- ここまで -->を取得したいのですが
どうすれば良いですか?

"/<!-- ここから -->(.*)<!-- ここまで -->/"
で読めませんでした
0064nobodyさん2007/03/24(土) 13:41:28ID:???
>>62
> 不用意に最短マッチ使ってるとパフォーマンスで泣くよ?

kwsk
0065nobodyさん2007/03/24(土) 16:11:22ID:???
$text = file_get_contents(なんちゃらかんちゃら);
mb_ereg("<!-- ここから -->(.*)<!-- ここまで -->", $text, $data);
echo $data[1];

改行に邪魔されてるんだろう
0066nobodyさん2007/03/25(日) 02:07:05ID:???
>>65
その記述だとパターンの部分でエラーがでない?
0067nobodyさん2007/04/07(土) 00:58:14ID:YCq54Nw2
始めまして。
C#で、正規表現でyyyy/mm/dd書式をどう表現するのでしょうか?
ちなみに、.NETの正規表現はPerl互換だそうです。
0068nobodyさん2007/04/07(土) 04:03:00ID:???
>>67
Datteクラスかなんかに文字列食わせて、例外飛ぶかどうかで
判定したら?

正規表現でやると 9999年13月35日をうけつけてもいいってのなら
  \d{4}/\d{2}/\d{2}
かな。
月と日は頑張ればなんとかできるけどめんどくさいからやらない。

0069nobodyさん2007/04/08(日) 02:12:40ID:EVMLEL7f
>>68
ありがとうございます。
実は、正規表現Validatorを使っているのです。
0070nobodyさん2007/04/08(日) 16:37:48ID:???
>>68
ああ、そういうことなのね。

一応注意しておくけど、C#の文字列のエスケープも\を使うので
プログラムに書くときは
  "\\d{4}..."
のように\を重ねるか、
  @"\d{4}.."
のような\が特別扱いされない形式にしてね。
0071nobodyさん2007/04/15(日) 02:12:22ID:v7Ys668x
php5です。ファイルのフルパスをディレクトリ,ファイル名,拡張子に分割してその配列を返したくてこう書きました。

$pattern1 = '`^(.*)(?:[/\\\](.*)){1}$`';
preg_match($pattern1, $fullpath, $match1);
$pos = strpos($match1[2], '.');
if($pos === false){
return array($match1[1], $match1[2]);
}else{
$pattern2='`^(.*?)\.(.*)$`';
preg_match($pattern2, $match1[2], $match2);
return array($match1[1], $match2[1], $match2[2]);
}

必ず拡張子があるなら一度のpreg_matchでキャプチャ出来たのですが
拡張子無しファイル混じりだった場合の正規表現がうまく思いつかずに二段階(三段階?)になってしまいました
でもpreg_matchやってその中で'.'探して、あったらさらにpreg_matchというのはまわりくどいように思います

この処理を一度にこなす正規表現の考え方のヒントをください
0072nobodyさん2007/04/15(日) 02:14:51ID:???
ああ半角空白の連続ダメなんだっけ インデント消えちゃた
0073nobodyさん2007/04/15(日) 03:03:32ID:???
>>71
http://jp.php.net/manual/ja/function.dirname.php
及び関連項目を参照。
0074732007/04/15(日) 03:04:35ID:???
あ、ごめん。正規表現スレだったね。無視して。
0075732007/04/15(日) 03:10:35ID:???
で、考えてみたんだけど、

$path = '/abc/def.g/eee.txt';
preg_match('/(.*?)¥/([^¥/]*)¥.([^¥/.]*$)/', $path, $match);
print_r($match);

こんな感じでどう?
0076732007/04/15(日) 03:17:28ID:???
これじゃ拡張子のない場合に対応できないか。
/(.*?)¥/([^¥/]*?)(¥.[^¥/.]*)?$/
でどうかな。スレを汚してしまってすまん。
0077nobodyさん2007/04/15(日) 09:05:07ID:???
PHPなら、dirnameとbasenameつかえば正規表現なんか使う必要一切ないだろ
0078nobodyさん2007/04/15(日) 11:13:03ID:???
>>77
>>73-74
0079712007/04/15(日) 11:28:41ID:???
正規表現無しだとこんな感じでした

$p = pathinfo($fullpath);
$temp = explode('.',$p['basename'],2);
$p['name'] = $temp[0];
if(isset($temp[1])){
 $p['ext'] = $temp[1];
}

>>76を参考にして正規表現で書けました

$pattern = '`^(.*)[/\\\]([^.]*?)(?:\.(.*))?$`';
preg_match($pattern, $fullpath, $match);

ありがとうございました
0080nobodyさん2007/05/03(木) 19:11:49ID:meD6A7ah
phpで携帯電話の絵文字を取り除くようpreg_replaceを使っているのですが、
絵文字が複数含まれた文字列?などでうまく取り除けません。
こんな感じにしているのですが原因やおかしな点などご教示ください。お願いします。

$str = '絵文字が含まれる文字列';
$emojiSjisChars = '(?:[\x00-\x7F\xA1-\xDF]|(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]))';

#DoCoMoの場合
$str = preg_replace('/\G(' .$emojiSjisChars. '*?)(?:\xF8[\x9F-\xFC]|\xF9[\x40-\x49\x50-\x52\x55-\x57\x5B-\x5E\x72-\x7E\x80-\xB0])|(?:\xF9[\xB1-\xFC])/', '$1', $str);

#AUの場合
$str = preg_replace('/\G(' .$emojiSjisChars. '*?)(?:[\xf3\xf6\xf7][\x40-\xfc]|\xf4[\x40-\x8d])/', '$1', $str);

#Softbankの場合
$str = preg_replace('/\G(' .$emojiSjisChars. '*?)\x1B\x24[E-G].*?\x0F/', '$1', $str);
0081802007/05/03(木) 19:17:55ID:meD6A7ah
すいません。↑の$emojiSjisCharsは$sjisCharsの命名間違えです。
0082nobodyさん2007/05/03(木) 19:26:15ID:???
ちゃんと読んでないけど
(?:絵文字のコード) な部分を (?:絵文字のコード)+ にするだけではないの?
0083802007/05/03(木) 20:24:41ID:meD6A7ah
>>82
レスありがとうございます。
下のように+を入れましたがダメでした。
色々考えているとどんどん分からなくなってきました...
おかしな点があれば引き続きご教示お願いします。

#DoCoMoの場合 ※見にくいので表示上改行します。
$str = preg_replace(
  '/\G(' .$emojiSjisChars.'*?)
    (?:\xF8[\x9F-\xFC]|\xF9[\x40-\x49\x50-\x52\x55-\x57\x5B-\x5E\x72-\x7E\x80-\xB0])+|
    (?:\xF9[\xB1-\xFC])+/', '$1', $str);
0084nobodyさん2007/05/04(金) 00:29:52ID:???
オライリーの詳細正規表現の本って
通常のと第2版ってのがあるけどどっちがいいのよ?
0085nobodyさん2007/05/04(金) 03:16:56ID:???
>>84
通常のって初版のことかい?
そりゃあ新しい方が。

具体的にどう変わったか覚えてないのでオライリーのサイトを見たけど、
Perlの対象が5.8にあがっているのと、.JAVAとNETの説明が増えたとからしい。
0086nobodyさん2007/05/10(木) 19:57:43ID:???
php4.3.11です
---------------------------------
$str = <<< DOC_END
あああああ
いいいいい
<html_start>
ううううう
えええええ
<html_end>
おおおおお
DOC_END;

$pattern = "/<html_start>(.*)<html_end>/";
$replacement = 'aaaabbbb';

$res = preg_replace($pattern, $replacement, $str);
print_r($res);
---------------------------------
と出力してみましたが何も表示されませんでした。
ホントは「あああああいいいいいaaaabbbbおおおおお」と出て欲しかったのですが…。
最終的には<html_start><html_end>で囲まれた範囲に
PHPのhtmlspecialchars()やnl2br()関数を適用して出力したいです。
0087nobodyさん2007/05/10(木) 20:35:51ID:???
>>86
> $pattern = "/<html_start>(.*)<html_end>/";

「 ^ や $ があるってことは正規表現って行単位?複数行の場合は?」とか思いながら

$pattern = "/<html_start>(.*)<html_end>/s";

にして試す。で、「s って何だよ、こんにゃろ」と思いながらマニュアルの「パターン修飾子」のとこを読む。

うちのPHP5さんでは元のコードでも「何も表示されない」にはならなかったな。
 
ブラウザ出力: あああああいいいいい うううううえええええ おおおおお
ソース: print_r($str) な感じ
0088nobodyさん2007/05/10(木) 20:51:04ID:???
>>87
s修飾子で動作しました!ありがとうございます。

>「s って何だよ、こんにゃろ」と思いながらマニュアルの「パターン修飾子」のとこを読む。
関数のページばかりみて
http://jp.php.net/manual/ja/ref.pcre.php
http://jp.php.net/manual/ja/reference.pcre.pattern.modifiers.php
のページの存在に気がつきませんでした…。

あとは関数を適用する方法を探してみますっ!
0089nobodyさん2007/05/10(木) 21:18:19ID:???
案外この手の質問したい人もいるんだね
0090862007/05/14(月) 15:45:03ID:???
後方置換する時に関数かましたくマニュアル眺めてたら「e修飾子」をみつけたのですが
>>87の「S修飾子」と同時に使おうと
$pattern = "/(.*?)<html_start>(.*)<html_end>(.*?)/se";
$replacement = "'\\2''\\1''\\3'";

こんなコードを書いてみた所
Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING
Failed evaluating code:
といった感じで怒られます
修飾子2個は同時に使えないのでしょうか…?
0091862007/05/14(月) 17:55:10ID:???
>>86ですが
自分で見返してたらこれは既に正規表現でなくPHPの質問な気がしてきましたので該当スレに
移動しますです。
スレ違、申し訳ありませんでした。
0092nobodyさん2007/05/17(木) 13:08:20ID:???
IPを正規表現でチェックしたいのですが
210.000.111.1〜210.000.111.255
215.100.000.1〜215.100.000.255
の2つに当てはまる場合、TRUE(int1)をかえすにはどうすればいいでしょうか?
以下のようにやってみたのですが他のIPでもint(1)がかえってきます。

preg_match('/^210\.000\.111\.([0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ || ^215\.100\.000\.([0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/', $_SERVER['REMOTE_ADDR'])
0093nobodyさん2007/05/17(木) 13:53:20ID:???
>>92
正規表現で foo || bar みたいなのはないっしょ。
/^(210...(中略)...|215...(中略)...)$/ みたいな。

アドレスの範囲のチェックをするなら正規表現使わない方が良いと思うけどね。
0094おながいします2007/06/06(水) 13:28:10ID:iKhV2zih
すみませんが、価格にマッチする正規表現を教えていただけないでしょうか。

例
\1,000,000,000
\12,345
\1,230
\200
\10


数字3つごとに、カンマが入り、先頭に円マーク(\)のくるものです。

判らないためググッたのですが、正規表現に関する本ばかり検索結果として出てきまして…。
0095おながいします2007/06/06(水) 13:29:35ID:iKhV2zih
上の>>94ですが、使用言語はPHPです。
0096nobodyさん2007/06/06(水) 13:41:59ID:???
それは、「\12,1232,32」みたいなのははじきたいの?
0097nobodyさん2007/06/06(水) 13:49:54ID:???
「正規表現 カンマ」とかでぐぐってみると・・・
0098nobodyさん2007/06/06(水) 14:54:17ID:???
>>98
穴だらけだけどこんなんのこと?
$hoge = "\1,000";
if(ereg(".*[0-9,\\]",$hoge)):
echo "ok";
else:
echo "ng";
endif;
0099nobodyさん2007/06/06(水) 15:08:26ID:???
>>98
つ[ http://www.google.co.jp/search?hl=ja&q=%E9%87%91%E9%A1%8D%E3%80%80%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE&lr= ]
0100942007/06/06(水) 17:22:28ID:???
>>96 >>97 >>98 >>99
皆様、ありがとう御座いました。
「価格 正規表現」、「値段 正規表現」でググってました(汗)
0101nobodyさん2007/06/30(土) 13:42:20ID:???
(?:pattern),および(?>=pattern)が認識されないエディタにおいて、
$obj->method();の「method」のみにマッチさせるにはどうすればいいでしょうか。
ちなみに(?=pattern)は使えます。
■ このスレッドは過去ログ倉庫に格納されています