X



正規表現道場 Part2

0001nobodyさん
垢版 |
2012/09/19(水) 18:58:43.51ID:bdgNsY2f
【正規表現道場の掟】

・言語不問

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

正規表現と関係ない話・質問は他スレへどうぞ。

前スレ
正規表現道場
http://kohada.2ch.net/test/read.cgi/php/1168450843/
0042nobodyさん
垢版 |
2013/09/15(日) 10:43:39.46ID:???
>>40
使ったこと無いけど、"韓国"だったら完全一致なのでそのまま正規表現使わずに書けると思うけど
0043nobodyさん
垢版 |
2013/09/15(日) 15:21:48.42ID:???
2ch専ブラにおける2chmateのデバッグ用文字列のみの書き込みをNGにしたいです

2chMate 0.8.5.6 dev/HTC/HTL21/4.1.1
2chMate 0.8.5.4/SHARP/SBM003SH/2.3.4

↑こんなやつです

一応専ブラはjanestyleということでどなたか教えていただけませんでしょうか
0044nobodyさん
垢版 |
2013/09/16(月) 04:52:23.59ID:V1KLg8Lz
韓|トンスル|ニダ|
004539
垢版 |
2013/09/16(月) 18:13:41.90ID:???
>>41
マッチしない場合は無いようでした。
phpの設定の問題でpreg_matchがマッチできずfalseを返す場合があるらしいです。
0046nobodyさん
垢版 |
2013/09/19(木) 16:03:12.92ID:XGTpu0pg
最近2ちゃんで同じ文字列を数行繰り返す荒らしがいますが

最近2ちゃんで同じ文字列を数行繰り返す荒らしがいますが

最近2ちゃんで同じ文字列を数行繰り返す荒らしがいますが

↑こんな感じです
改行を挟まない場合もあります

Janeでこれをあぼーんしたいんですが
同じ文字列が数行続いたかを調べられる正規表現はありませんか
004846
垢版 |
2013/09/19(木) 23:50:13.04ID:???
>>47
ありがとうございます
無事あぼーん出来ました
直前の自分のレスも消えてます
0049nobodyさん
垢版 |
2013/09/22(日) 00:52:59.03ID:PBzP1rLU
下の文字列から最短で「NN are_VBP strongly_RB supported_VBN」を抜き出すのに
NN\s.*?VBNでうまくいかない(最長マッチが返ってくる)のですが、何が悪いのでしょうか?

In_IN Israel_NNP ,_, freedom_NN of_IN opinion_NN and_CC risk_NN taking_NN are_VBP strongly_RB supported_VBN ._.
0050nobodyさん
垢版 |
2013/09/22(日) 02:25:21.73ID:V8cai0+K
それだと最初に出現するNN\s位置からマッチングが始まって、
最短で後続するVBNまでがマッチする

こうじゃないか?
.*(NN\s.*?VBN)
005149
垢版 |
2013/09/22(日) 08:30:46.88ID:???
>>50
ありがとうございます。
しかし、、、.*(NN\s.*?VBN) だと、今度は、行全体がマッチしてしまいます。。。
ムムム
0052nobodyさん
垢版 |
2013/09/22(日) 14:36:58.31ID:???
NN arからじゃ駄目なん?
NNじゃ>>50の言うとおり最初のNNからマッチするんだし
005349
垢版 |
2013/09/22(日) 15:17:49.08ID:???
>>50
>>52
ありがとうござしました。
プログラム板でも聞いてみたところ、下のような表現を教えてもらいました。
NN\s((?!NN).)*?VBN
0054nobodyさん
垢版 |
2013/09/22(日) 20:33:23.35ID:???
>>53
結果教えてくれてありがと
前方参照否定位置指定子かー

NNが来ないNN空白〜VBNにマッチするのね
0055nobodyさん
垢版 |
2013/09/23(月) 15:50:05.13ID:???
ええい、お前はもう下がっておれ
webprog板の面汚しめ
0056nobodyさん
垢版 |
2013/09/23(月) 21:29:41.29ID:???
php使いが鼻で笑われる所以(´・ω・`)
0057nobodyさん
垢版 |
2013/09/23(月) 21:37:40.88ID:???
(´・ω・`)←この顔文字、3年ぶりぐらいに見たw
0059nobodyさん
垢版 |
2013/10/07(月) 05:09:32.74ID:???
PHP5.4です。
'hoge山田
太郎2様hoge'
(2の数字は色々変わります)
の中から'太郎2様'をマッチさせたいのですが
/山田[\s\S]*?(/太郎.*?様/u)様/u
でうまくいかないです。どなたか教えて下さいまし。。。
0061nobodyさん
垢版 |
2013/10/07(月) 16:36:42.52ID:???
>>60
なんとー
ありがとうございます
0062nobodyさん
垢版 |
2013/10/09(水) 23:36:54.74ID:???
行の最後に[a-z0-9]が9文字、はどう指定するんでしょうか
([a-z0-9]){9}$
$(([a-z0-9]){9})
と思ったのですが、うまくいかないです。
0064nobodyさん
垢版 |
2013/10/10(木) 11:09:37.77ID:???
ありがとうございます!
0065nobodyさん
垢版 |
2013/10/31(木) 18:34:38.76ID:GYE7WPbH
ab(cd)efg
とある時
(.*?)
で"(cd)"は返ってきますが、
"cd" とカッコの中身だけを取りたい時はどうすればいいでしょうか
"(" と ")" を置換するしかないですか?
0066nobodyさん
垢版 |
2013/10/31(木) 18:49:48.33ID:???
言語、、つか環境は?
0067nobodyさん
垢版 |
2013/10/31(木) 21:18:35.06ID:odoD21Ul
エスケープしろよ
0068nobodyさん
垢版 |
2013/11/29(金) 11:12:23.82ID:???
PHP5で
パターンは、/<a>.*<\/a>/
対象文字列は、<a>テスト1</a><a>テスト2</a>
preg_match('/<a>.*<\/a>/', '<a>テスト1</a><a>テスト2</a>', $result)

でマッチした文字列は、
$result[0]:<a>テスト1</a>
$result[1]:<a>テスト2</a>
となることを期待しているのですが、

実際は、
$result[0]:<a>テスト1</a><a>テスト2</a>
となりました。

<a></a>は独自タグで間に入る文字列長、フォーマットは不定です。
どうすれば期待通りの振る舞いに出来るでしょうか?
0069nobodyさん
垢版 |
2013/11/29(金) 11:36:29.05ID:???
68です。

すみません。訂正します。

× preg_match('/<a>.*<\/a>/', '<a>テスト1</a><a>テスト2</a>', $result)
○ preg_match_all('/<a>.*<\/a>/', '<a>テスト1</a><a>テスト2</a>', $result)
0070nobodyさん
垢版 |
2013/11/30(土) 00:49:11.30ID:ykQSlGiP
?
0071nobodyさん
垢版 |
2013/11/30(土) 23:20:57.87ID:???
正規表現の練習になるお題ください
0072nobodyさん
垢版 |
2013/12/04(水) 06:52:39.64ID:???
>>71
お題が欲しけりゃJaneのReplaceStr.txtとかNGEx.txtとか自分でいじってみればいいんじゃないの?
練習はReplaceStr Toolでやれるから。
グループ化を使って解析させると幾分わかりやすくなる。
0073nobodyさん
垢版 |
2013/12/08(日) 20:14:52.93ID:1LHzvpJQ
おしえてください。

テーブルタグで囲っている、下記のような
HTMLの表があります。


名前 | ふなっしー
住所 |  東京都港区赤坂
電話番号 | 090-0000-0000


ふなっしー
東京都港区赤坂
090-0000-0000

という結果を期待して

名前(.*)
住所(.*)
電話番号(.*)


と書いたんですが、使い方を間違っているのか?
うまくいきません。
他の記述方法はないでしょうか?
0074nobodyさん
垢版 |
2013/12/20(金) 03:59:14.24ID:JjVtc12l
ム板の本スレが新しくなったため報告させていただきます。

■本スレ
Regular Expression(正規表現) Part12
http://toro.2ch.net/test/read.cgi/tech/1387257592/

■注意
工作員がわざと重複させて立てた偽スレを本スレだと偽って宣伝に来る可能性があります。
本スレは上記のみですので十分ご注意ください。
0075nobodyさん
垢版 |
2013/12/22(日) 03:59:29.94ID:???
>>72
ReplaceStr Toolって?ググったが出てこない
0076nobodyさん
垢版 |
2013/12/22(日) 08:24:16.49ID:???
>>75
これだろ。
ttp://1st.geocities.jp/neeetest/RepStrTool_2.8.zip
0080nobodyさん
垢版 |
2014/01/16(木) 03:06:09.07ID:???
計算機数学 町田 元
http://www.amazon.co.jp/dp/4627821506

大阪大学 - コンピュータ数学
https://koan.osaka-u.ac.jp/syllabus_ex/campus?view=view.syllabus.ex.refer.sogo.search
&func=function.syllabus.ex.refer&nendo=2009&j_s_cd=09&j_cd=090508&langkbn=j

※ 全部正規表現に関係するリンクなんで荒らしではないです。
正規表現に関わるオートマトンの知識を付けたい方には参考になると思います。
0081nobodyさん
垢版 |
2014/01/18(土) 22:50:11.07ID:???
有限オートマトンと正規表現 (ヤギ 野菜 狼)
ttp://www.i.kyushu-u.ac.jp/~takeda/Lectures/.../ComputationTheory01.pdf?
0082nobodyさん
垢版 |
2014/01/19(日) 07:18:17.70ID:???
ある文字列を含まないものにマッチする正規表現
(?:(?!foo).)*

^(?:(?!foo).)*o$ → 「foo」 にマッチ出来ない。

先読みを使わない正規表現ならマッチ出来る。
→ (?:(?!foo).)* は厳密には間違い。

Q、では先読みを使って正しく動作させるにはどう書くべきか?
0083nobodyさん
垢版 |
2014/01/19(日) 11:23:45.74ID:???
お望みの先読み使って書くなら /fo(?!o)/

だろうが、

こんなの使うくらいなら

if (/foo/) {

} else {
  ※ここに書いたほうがいいに決まってる
}

で、もはや正規表現使うコストももったいないくらいだから
普通は strpos()みたいな関数使うべきだろう。
0084nobodyさん
垢版 |
2014/01/19(日) 15:12:27.67ID:U6WWS19r
先頭一致とか後方一致はsubstr使ってる
iオプション必要なら代わりにlc
0086nobodyさん
垢版 |
2014/01/19(日) 17:13:11.44ID:???
>>83
>>82の内容を理解出来てないね・・

(?:(?!foo).)* → fo にマッチ
o$ → o にマッチ

これ足して foo にマッチ「する」のが期待する文字列否定の動作。
fo の中に foo は含まれていないので fo にはマッチしなければならない。

>関数使うべき
マラソン選手に車使うべきって言ってるようなもん。
0087nobodyさん
垢版 |
2014/01/21(火) 04:23:32.47ID:???
正解はこちら↓

Perl正規表現雑技 - ある文字列を含まないものにマッチする正規表現
http://www.din.or.jp/~ohzaki/regex.htm#Without
0088nobodyさん
垢版 |
2014/01/24(金) 01:21:47.01ID:???
うーむ、オートマトンの勉強というか、まだ触りしか学んでないんだが
既に文字列否定の正規表現を簡単に作れるようになってしまった。

チャリの運転と同じで、一旦出来るようになるとなんてことないね。
0089nobodyさん
垢版 |
2014/01/24(金) 05:08:57.49ID:???
(次のお題)

abc かつ def を含まない文字列を表す正規表現を作れ。ただし先読みはNG。
0090nobodyさん
垢版 |
2014/01/25(土) 14:00:24.10ID:peRg4Ln+
お題が提示されておりますが、質問よろしいでしょうか。
言語は Java(Android開発) です。

やりたいことは、
 ・'a', 'b', 'c', '*' の4つの文字が使われた文字列を分割する
 ・'a*', 'b*', 'c*' は1文字として扱い、'*'のみの物は無い
になります。

例えば "aba*cb*" の場合は
a
b
a*
c
b*
に分割したいです。

どのように書けば良いのでしょうか、ご教授願います。
0091nobodyさん
垢版 |
2014/01/25(土) 17:37:15.39ID:VUYYCfMh
([abc]\*?)
009390
垢版 |
2014/01/26(日) 13:40:59.38ID:???
>>91
ありがとうございました。勉強になります。

>>92
>>1も読めない糞は2chには向いていないと思うよ。
もう何十年も居座っていると予想されるが、そろそろ自覚しなよ。
0094nobodyさん
垢版 |
2014/01/26(日) 23:09:13.31ID:???
ここはもう荒らしの本拠地になってるから仕方がないよ。
わざわざ煽りにム板まで出張してきてるし。
0095nobodyさん
垢版 |
2014/01/27(月) 00:48:44.89ID:???
こちらは精神異常者の隔離スレとなっております
0097nobodyさん
垢版 |
2014/01/29(水) 03:59:46.05ID:???
レベル高いスレにただいま。
0098nobodyさん
垢版 |
2014/01/29(水) 04:05:21.14ID:???
荒らしの住み処
ただのクソスレ
0099nobodyさん
垢版 |
2014/01/29(水) 05:11:24.62ID:???
ところで向こうの267は雑技たんなのかな?266、雑技のネタに使ってもよかですたい。
0100nobodyさん
垢版 |
2014/01/29(水) 08:45:10.20ID:???
>>99
当たりw
266の書き方は考えたけど,今回のケースでは267の書き方で大丈夫と考えた.
そういや質問者は「1」を含まないって書いてあるのに,なぜ「123」? とは思ったなw

後ろに他の正規表現を続けたりするとバックトラックして,
271の通りの可能性があるから初心者には266の方がいいのは確か.

ただ,他にもいろいろ考え出すと,最も内側のものだけ削除したいのなら,
ABC(?:(?!123|ABC|DEF).)*DEF
と書いた方がいいとかもある.

ちなみに266のミソは↓の辺りで微妙に使っていたりする.
http://www.din.or.jp/~ohzaki/regex.htm#NoEndTag
0101nobodyさん
垢版 |
2014/01/29(水) 15:23:04.24ID:???
>>100
ああ、考えてみればABCも入れたほうがいいね。質問者の対象データが対になってる
データだったから必要性を感じなかったが入れるべきだった、さすが雑技たん。

>なぜ「123」?
1というのは実データとは違う省略形と考えた。
初心者には文字と文字列の違いが分からないから文字列のつもりで1と書いてしまった
可能性がある。そこで文字列に対応しておけば1文字にも対応出来るってわけ。

>ABC(?:(?!123|ABC|DEF).)*DEF
これが基本形やね。高速化するなら*+とか、もっとやるなら[^1AD]*+使ってごちゃごちゃ書いたり。

>NoEnd
ミソは否定の中に分岐を入れることだからそれとはちょっと違うw
それと <\2> だと <font> になってしまうで・・ <\2\b やね。
0102nobodyさん
垢版 |
2014/01/30(木) 00:29:41.02ID:???
>>101
>1というのは実データとは違う省略形と考えた。
なるほど.確かに,初心者ほど状況説明が下手だからね.

>それと <\2> だと <font> になってしまうで・・ <\2\b やね。
単純なミスだな.指摘ありがとう.
0103nobodyさん
垢版 |
2014/01/30(木) 07:11:02.94ID:???
・範囲内で文字列を含まない正規表現

$_ = "zzzABC XYDEFzzDEFz";
if ( m/
# Perl 5.10 以降で有効
ABC
[^XAD]*
(?:
(?!XYZ|ABC|DEF).
[^XAD]*
)*
(*PRUNE) # バックトラックステートの削除
(*SKIP) # 次回の走査開始位置をここに飛ばす
(?:XY?)? # XYZとDEFの競合を想定した取りこぼし回収
DEF
/xgsiaap )
{ print "match! <".${^MATCH}.">"; }
else
{ print "no match."; }

>>102
修正乙!
0104nobodyさん
垢版 |
2014/01/30(木) 13:46:05.59ID:???
修正乙の後でアレなんだけど、実際に動かしてみたらだいぶおかしいから手直ししてみたよ、と。

while ($html =~ /
<(NOBR|CODE|B|PRE|FONT)\b

(?=
(
(?:(?!<\/\1>).)*?
(?:<\1\b|$)
)
)
/sixg

) {
print "<".$1.$2, "\n";
}

------------- perl.htm -------------
<b><font><pre><b>aaa
------------- perl.htm -------------

*? はなるべく使いたくないなぁ・・ [^<]*+ を使って最適化したいw
0105nobodyさん
垢版 |
2014/01/31(金) 02:30:50.66ID:???
>>103
(*VERB:ARG) ってのは知らなかったなぁ.
今回のケースだと(*PRUNE)は(?>pattern)で置き換えができると思うが,
マニュアルの 「(*PRUNE) は (?>pattern) 単独では表現できないケースを扱うために使えます。」ってのがどういうケースなのか想像できん.

>>104
修正ありがと.
元のやつだと後ろを吸い込んじゃうからマッチ位置が先に進んでしまう.
そうならないように先読みを使うと,先読み部分は後方参照に含まれなくなるから,先読みの中で改めて補足が必要って感じだね.
0106nobodyさん
垢版 |
2014/01/31(金) 04:37:54.39ID:???
>>105
>単独では
・・・ ( ・・・ (*PRUNE) )
みたいに ( ) で分断されてる場合とか? (?> だと2つ以上必要になる。

>マッチが先に
当たり〜。printのとこは""の中にまとめて書いても大丈夫だったのか、勉強になりますた。
改めて修正乙。
0107nobodyさん
垢版 |
2014/01/31(金) 10:29:26.11ID:???
>>103
「XYZとDEFの競合」ってのはXYZの後半封舶ェがDEFの前半部分と同じ場合ってことかな?
例えば,xydとdef,とか,xdeとdefみたいな

もしそういう,後半部分と前半部分が重なる場合を考え出すと,話がもう少しややこしくなる.

つまり,ABCDとCDEFがキーだったときに,ABCDEFという文字があったら,
それはABCD+EFと解釈するのか,AB+CDEFと解釈するのか,という問題.

その解釈がすべて前方優先なのか,すべて後方優先なのか,それともキーの相互の優先度で決まるのか,
あるいは,あらゆる可能性を許すのか,あらゆる可能性を許さないのか.

キー自身が重なる場合もある.
例えば,ABCABみたいなキーだったとき,ABCABCABは,ABCAB+CABなのか,ABC+ABCABなのか.
0108nobodyさん
垢版 |
2014/01/31(金) 10:34:35.37ID:???
>>106
>・・・ ( ・・・ (*PRUNE) )
なるほど,括弧の深いところで使うと,(?> で表現するのは大変そうだ.
しかも,もしそれが中間レベルで分岐してたりすると,(?> では表現しきれないかな.
0109nobodyさん
垢版 |
2014/01/31(金) 16:13:45.49ID:???
>>107
ぶっちゃけその辺は何も考えてない。試作品とかテンプレートみたいな感じで作っただけ。
競合対策の部分は普通の使い方をするならいらないね、HTMLやXMLタグで挟まれた文字列にマッチさせるときとか。
こういうの以外に使い道が思い当たらないし。(だったら付けるな)

>>108
>分岐
なるほど、(?> ではお手上げだ。俺も年末に覚えたばかりでよく分かってない。
0110nobodyさん
垢版 |
2014/02/01(土) 16:48:52.03ID:???
## (*COMMIT)

$_ = "12";
if (
m/^1((*COMMIT)3|2)/
){ print "match!\n"; }
# 分岐の中で踏まれると以後ほかの分岐要素を走査することがなくなる。
# 現在の分岐要素がマッチ失敗したら全体もマッチ失敗となり検索はそこで完全終了する。

m/^1(*COMMIT)(3|2)/
# 下位層の分岐は走査され、マッチが成功する。

$_ = "12";
@test = $_ =~ m/^1(*COMMIT)A|\d/g;
print "@test\n";
# /g でも次位置からの走査は行われない。

@test = $_ =~ m/^1(*COMMIT)|\d/g;
# 結果 = 1 2 。マッチが成功した場合は走査を止めることはない。(失敗したときだけ止める)
0111nobodyさん
垢版 |
2014/02/01(土) 17:24:27.45ID:???
Q、(*COMMIT) とは逆にマッチが成功したときだけ /g を止める最も簡単な手段は何か?

$_ = "123";
@test = $_ =~ m/1|2|3/g;
print "@test\n";

↑2 がマッチ成功したときに /g を止め、3がマッチしないようにする。
フラグ変数を用意、チェックすれば可能だがもっと手軽な手段はないか。
0112nobodyさん
垢版 |
2014/02/02(日) 07:59:18.35ID:???
う〜ん、/g はループなのに break する方法が用意されていない。
COMMIT があるのにこれがないのはとても不可解だ。

# 先読みの中の (*SKIP) は機能しない。
@test = $_ =~ m/1|2(?=.*(*SKIP))|3/g;

# while 文の last を使う。
$_ = "123";
while ( m/1|2|3/gp )
{ print "${^MATCH}\n";
last; } # 1 で止まる。

# (?{code}) で last → 効果なし
while ( m/1|2(?{ last; })|3/gp )

# while 文に名前を付けて (?{code}) で last → 効果なし
TEST : while ( m/1|2(?{ last TEST; })|3/gp )

perl陣営に言えば新しいコマンド作ってくれそうだなぁ。
0113nobodyさん
垢版 |
2014/02/02(日) 08:47:00.66ID:???
# (?-g) → 効果なし
while ( m/1|2(?-g)|3/g )

# 苦肉の策 (現実的でない)
while (
m/(1)|(2).*|(3)/g
)
{ print "${^N}\n"; }

# 苦肉の策 + 最後の空文字列にマッチしない対策 (現実的でない)
while (
m/\z(*COMMIT)(*F)|(1)|(2).*|$/g
)
{ print "match! ${^N}\n"; }
0114nobodyさん
垢版 |
2014/02/02(日) 10:19:23.61ID:???
>>111
>>112 >>123
/g がループというのはちょっと違う.
リストコンテキストで評価したときはループと言えるが,スカラーコンテキストで評価したときはループではなく,
単に前回マッチした場所を覚えていて続きからマッチングを行うというだけ.

この問題はリストコンテキストで /g を評価したときに,マッチ成功後に途中で止めるいい方法はないかって言う問題だと解釈した.
スカラーコンテキストで評価したときに止めるんなら last を使えば簡単に止まる話.

つまり,while を使っていいんなら,
while (/1|2(*:STOP)|3/g) {
push(@test, $&);
last if $REGMARK eq 'STOP';
}
print "'@test'\n";

リストコンテキストで評価したときに途中で止めるには,かなり条件が限定されるが,
@test = $_ =~ m/(?(?<=2)\G(*COMMIT)(*FAIL))(?:1|2|3)/g;
ぐらいしか思いつかなかった.
これではフラグを使った方が簡単だろう.
0115 ◆QzqhRqBYxktP
垢版 |
2014/02/02(日) 14:00:26.89ID:???
>>114
>ループというのはちょっと違う
そのへんはちゃんと理解してるから大丈夫。foreachとか<>みたいなつもりで書いてるから。

>リストコンテキストで /g を評価したときに,マッチ成功後に途中で止めるいい方法はないか
その通り。

>(*:STOP)
これはフラグ変数を使うやり方とまったく同じだからボツ・・。{ } の中で last するのはナシ。
m/ / の中で止められないか、という話だから。

しかも$REGMARKと$REGERRORは予期しない動きをすることがあるから
普通にフラグを使ったほうが確実。(後述)

>これではフラグを使った方が簡単だろう
やっぱそうかぁ、雑技たんでもダメなら無理そうだね。考えてくれてありがとう。
0116nobodyさん
垢版 |
2014/02/02(日) 14:08:53.79ID:???
## $REGERROR

# マッチ失敗でも$REGERRORが偽を返す例
$_ = "11";
m/^(*MARK:NAME)12/;
if ($REGERROR){ print "yes\n" }else{ print "no\n"; };

結果 → no

# 2 を (?!) や (*FAIL) に変えると・・?
m/^(*MARK:NAME)1(?!)/;

結果 → yes

2 を $ にすると no のまま。
0117nobodyさん
垢版 |
2014/02/02(日) 14:12:45.66ID:???
あれ、$REGMARK が予期しない動作になるデータはないや。
ごめん、使えないのは $REGERROR だけかも。
0118nobodyさん
垢版 |
2014/02/02(日) 14:30:37.56ID:???
>単に前回マッチした場所を覚えていて続きからマッチングを行うというだけ

あ、ちゃう、これ分かってなかった。場所覚えてるだけだったのか、違和感感じてたんだけど
やっと理解出来たよ、ありがとう。


あと雑技たんのサイトだけど
>回文にマッチする正規表現 # 再帰版

× (??{$palindrome})*
○ (??{$palindrome})?

だね。前者だと回文を繋げた文字列 121454989・・・ みたいなのを拾ってしまう。
0119nobodyさん
垢版 |
2014/02/02(日) 20:34:08.85ID:???
>>117
確かに $REGERROR は期待通りに動かないな.

>>118
回文の間違い指摘ありがとう.
0120 ◆QzqhRqBYxktP
垢版 |
2014/02/02(日) 20:50:07.49ID:???
おや、出来ちゃった・・

# リストコンテキスト + /p のマッチング中に break する。
$_ = "123";

@test = $_ =~ m/
1
|2
(?{ $last = "${^MATCH}"; })
(*COMMIT)(*F)
|3
/xgp;

push(@test,$last);
print "@test\n";

# リストコンテキスト + /p のマッチング中に break する。( push版 )
push(@test,
m/
1
|2
(?{ $last= ${^MATCH}; })
(*COMMIT)(*F)
|3
/xgp
,
$last
);

>>119
仕事はやっ!修正乙〜
0121 ◆QzqhRqBYxktP
垢版 |
2014/02/03(月) 07:41:48.62ID:???
↑× /p のマッチング中に → /g の間違い
----------------------------------------------
# 先読みの中の (*SKIP) は正しく機能する。(× >>112)

$_ = "123";
@test = $_ =~ m/1|2(?=.*\z(*SKIP)(*F))|3/g;
print "@test\n";
# 結果 → 1

# 先読みの中の (*SKIP) が失敗する例もある
@test = $_ =~ m/1|2(?=.*\z(*SKIP))(*F)|3/g;
# 結果 → 1 3
# perl内部の最適化の影響により (?=) より早く (*F) が判定されている?
# $REGERROR が期待通りに動かない原因も最適化が犯人? (最適化は 詳説 正規表現 参照)

----------------------------------------------

# \z で始まる正規表現 + while( /g )
while (
m/\z(?{ print "in code\n"; })/g
)
{ print "match!\n"; }

<結果>
in code
match!
in code

2回走査されてる。2回目は走査しといてマッチ失敗。/g により1つ先に進む動作の副作用?
(?{code}) が2回実行されるのでプログラムが想定外の動作になる可能性。
/g を忘れると走査開始位置が毎回先頭に戻り、無限ループになる。
0122nobodyさん
垢版 |
2014/02/03(月) 17:57:59.62ID:???
# リストコンテキスト + /g のマッチング中に break する。(perl 旧verl対応版)

$_ = "12223";

@test = $_ =~ m/
1
|2
(?{ $last = "$&"; })
.*\z # 余った文字列を全部マッチさせる。
|3
/xgs;

$test[$#test] = $last; # 最後の要素の入れ替え
print "@test\n";

これらを "break出来てる" と言うのはちょっとおこがましいかも知れない。やはり break コマンドが欲しい。
0123 ◆QzqhRqBYxktP
垢版 |
2014/02/04(火) 13:37:35.16ID:???
・$REGERROR を (?{code}) と入れ替えて実験

my $cnt = 0;
$_ = "11";
m/^(?{ $cnt++;})1(*F)/;
print "$cnt\n";
# 結果 → 1

my $cnt = 0;
$_ = "11";
m/^(?{ $cnt++;})12/;
print "$cnt\n";
# 結果 → 0

$REGERROR さんに無罪判決。冤罪でした。
0124nobodyさん
垢版 |
2014/02/04(火) 13:39:28.33ID:???
皆様、こんにちは 質問させてください

テキスト内の文字を置き換えるアプリ(Devas)で作業をしています
正規表現で文字検索と置き換えしたいのですが表現法がわかりませんので
詳しい方アドバイス下さいませんでしょうか?

テキスト内には

.(ドット)abc"IMG
.(ドット)def"IMG
.(ドット)ghr"IMG

など . と "IMG で囲まれた数パターンの文字列がありこれに元文字列を利用し .photo を付け加えたいのです

.(ドット).photo.abc"IMG
.(ドット).photo.def"IMG
.(ドット).photo.ghr"IMG

検索、置き換え 共に正規表現が使えるアプリなのですがそれぞれどう表現して良いのか教えてくださいませんか?
よろしくお願いいたします 
0125 ◆QzqhRqBYxktP
垢版 |
2014/02/04(火) 13:41:51.03ID:???
・開始タグと閉じタグの間に文字列を含まない正規表現 (正規表現 否定 除く)

$_ = "ABC ABC DEF ABCDEF";

while ( m/
# Perl 5.10 以降で有効
ABC
[^ADX]* # 先頭の文字を使った高速処理
(?:
(?:
DEF (*ACCEPT) # マッチ成功
|\K ABC # 今までマッチした文字列を捨ててリスタート
|XYZ (*PRUNE) (*SKIP) (*F) # NGワード検出、マッチ失敗
|. # ↑の3つ以外の1文字
)
[^ADX]*
)*
(*COMMIT) (*F) # DEFで閉じられないまま終端に到達。
/xgsiaap )

{ print "match! <${^MATCH}>\n"; }

# NGワード、開始タグ、閉じタグの競合は想定していない。
# 例、NGワード="</" 、 閉じタグ="</div>"
0126nobodyさん
垢版 |
2014/02/04(火) 20:09:35.38ID:xuvSG1oC
s/^\./.photo./g
行頭限定の場合
0127 ◆QzqhRqBYxktP
垢版 |
2014/02/05(水) 16:22:38.43ID:???
>>124
<検索>
\.([a-z\d]{1,4}"IMG\b)
<置換>
..photo.$1

\. を ( ) に入れてないのは処理効率を上げるため。
「abc」の部分は拡張子と考えて数字も許可した。(1文字以上4文字以下の英数字)

何かまずかったら遠慮なく。
0128124
垢版 |
2014/02/06(木) 18:00:16.14ID:???
たくさんレスいただきましてありがとうございます
お礼が遅れまして申し訳ありません

127様の \.([a-z\d]{1,4}"IMG\b) で無事検索できることができました
しかし置き換えでは マッチした文字列が ..photo.$1 に置き換わるだけで $1にマッチした語句が適応されません

検索結果
○○○○○○.abc" IMG が ○○○○○○..photo.$1 となります
希望では
○○○○○○.photo.abc" IMG となることです(単純に .拡張子 前に .photo を入れたい)

先の書き込みでの訂正がありました 申し訳ありません
検索したい文字列には " と IMG の間に半角スペースがありました

半角があっても上手く検索にひっかっかっていますが
上手く置き換えができないのはこの半角が原因なのでしょうか?

引き続きご指導いただければ幸いです よろしくお願いいたします
0129 ◆QzqhRqBYxktP
垢版 |
2014/02/06(木) 20:27:01.21ID:???
>>128
ごめんなさい、こちらにも見落としがいくつかありました。
( Devasにはメジャーな正規表現エンジンが使われていると考えて作りましたが違ったようです )

・通常版 (上行=検索、下行=置換)
\.[a-zA-Z\d]{1,4}" ?IMG\b
.photo\0

・拡張子を小文字に変換する版 (例 .JPG → .jpg )
\.([a-zA-Z\d]{1,4})(" ?IMG\b)
.photo.\L\1\E\2

・ 「"」 と IMG の間のスペースがあっても無くてもスペース1個にする版
\.([a-zA-Z\d]{1,4})" ?IMG\b
.photo.\L\1\E" IMG

# \L と \E を削除すれば拡張子の小文字変換はしなくなります。
# 本当は .photo.photo.jpg のような複数回置換による重複を防ぎたかったんですが
# この正規表現エンジンでは無理なようです。(>_<)
0130nobodyさん
垢版 |
2014/02/06(木) 22:22:42.47ID:???
>>129
度々のレスありがとうございます

正規表現エンジンにもいろいろなものがあるとは知りませんでした
お手数をおかけいたしまして申し訳ありません

いくつものパターンを示してくださいまして 
重ねて感謝いたします

通常版にて理想の変換ができました
今回教えて頂いたような知識を深めて、もっと便利にPCを使えるようになりたいと思います

勉強になりました ありがとうございます m(_ _)m
0131nobodyさん
垢版 |
2014/02/09(日) 02:41:58.21ID:???
質問させてください。
phpのpreg_match関数でwebページから文字列を抽出したいと考えています。
以下を使用して抽出していますが、改行が含まれると抽出ができませんでした。

$text = '/value="(.*?)" id="latest"/';
preg_match($text, $source, $matches);
$word = $matches[1];

色々調べて$textを以下のようにしてみましたが、うまくいきませんでした。
$text = '/value="(.*?)" id="latest"/s';
$text = '/value="([\s\S]*?)" id="latest"/';
$text = '/value="((\n|.)*?)" id="latest"/';

何故うまくいかないのかよくわかりません。
なにかアイデアはありませんでしょうか?
0132nobodyさん
垢版 |
2014/02/09(日) 08:07:39.87ID:J9pikab5
俺なら
/value="([^"]*)"\s+id="latest"/
0133 ◆QzqhRqBYxktP
垢版 |
2014/02/09(日) 17:20:31.79ID:???
× ' '
○ " "

というオチ?PHPは触らないから分からない。
0134nobodyさん
垢版 |
2014/02/09(日) 17:39:19.85ID:J9pikab5
PHPなんか触らないから分からないけど両端のすらすらが余計とかなんかね
0135 ◆QzqhRqBYxktP
垢版 |
2014/02/09(日) 18:09:22.12ID:???
ごめんなさい、PHPの解説サイト見たら ' ' でOKでした。
0136nobodyさん
垢版 |
2014/02/11(火) 10:03:59.12ID:???
PHPスレで聞いたほうが早いかも。原因が改行以外にある可能性も十分あるので
動かないサンプルコードをアップして見てもらえば確実に原因教えてもらえると思う。
0137nobodyさん
垢版 |
2014/02/11(火) 13:41:52.16ID:???
↑$source に入るHTMLファイルも見ないと原因が分からない可能性アリ。
0138 ◆QzqhRqBYxktP
垢版 |
2014/02/13(木) 23:18:13.09ID:???
再帰と (?( ) yes|no) の組み合わせが楽しすぎる。もしかしたら宝の山かも。
マトリョーシカの中にダルマを入れられる感じ。
0139nobodyさん
垢版 |
2014/02/15(土) 18:56:47.98ID:???
正規表現メモ
http://www.kt.rim.or.jp/~kbk/regex/regex.html#NOTINCLUDED
「調整中」


気付いてもらえたのかそうでないのかいまいち分からんす。
このサイトはあんまアテにしないほうが良さそうだ。
0140 ◆QzqhRqBYxktP
垢版 |
2014/02/16(日) 14:59:01.14ID:???
>>125 の疑問点

\K が分岐の先頭にあることで処理速度に遅れが出るかどうか調べる。
また、\K を使わない書き方とどちらが早いか調べる。
レスを投稿する