トップページ⇒tech
1001コメント322KB

正規表現 Part8

レス数が900を超えています。1000を超えると表示できなくなるよ。
0001デフォルトの名無しさん2011/03/26(土) 00:38:06.48
正規表現(Regular Expression)スレです。

質問する場合は実装言語や処理系ソフトウェア名を示しておくと話が早いです。

正規表現 Part7
http://hibari.2ch.net/test/read.cgi/tech/1268979408/
0809デフォルトの名無しさん2011/11/27(日) 23:54:06.93
>>807
正規表現は原則よくばりなマッチ(とれるだけとる)をするんだけど、この原則をひっくり返したものが、.*?
0810デフォルトの名無しさん2011/11/28(月) 07:30:19.02
もしかしたら
「0個か1個」を意味するメタキャラクタの"?"で、どういう理屈で最短一致になるのか?
という疑問かもしれん。


(量指定子)?

という表現ひとまとまりで、最短一致を表す正規表現となる。そういう約束。
この場合の"?"は「0個か1個」を意味するメタキャラクタとは別物。

行頭を表す"^"と、文字クラス内で否定を意味する"^"とが別物であるようなもの。
0811デフォルトの名無しさん2011/11/28(月) 13:31:24.66
>>808
>>809
>>810
説明不足なのにエスパーしてくれた>>810さんの通りでした
メタキャラクタの"?"とは切り離して考えないといけないんですね。

ありがとうございました!
0812デフォルトの名無しさん2011/11/29(火) 22:16:38.47
SoftalkWEBっていう2chスレ音声読み上げソフト使ってます。

そこで、
>>9
↑
みたいにレスに返事をする部分を
レス9へ返事

と変換したいのですが変換対象と変換結果をどのように指定すればよいでしょうか
0813デフォルトの名無しさん2011/11/29(火) 22:26:54.43
>>812
安価以外の「『>』×1〜2+数字」にも絶対反応するけどそれはどうするの?
0814デフォルトの名無しさん2011/11/29(火) 23:39:45.17
Javaでaaaa1.txt と bbbb2_2.txtというファイル名が有り、
aaaaと1、bbbb2_と2を抽出したい
どう書いたらいい?
0815デフォルトの名無しさん2011/11/30(水) 00:24:08.72
cccc22.txtだったらどうなればいいかとかいろいろ情報不足
0816デフォルトの名無しさん2011/11/30(水) 00:42:50.28
一応考えたのは
((^[a-zA-Z_\\-]+)|(^[a-zA-Z_\\-]+[\\-_]))(\\d+)\\.txt$
です
0817デフォルトの名無しさん2011/11/30(水) 00:48:44.55
訂正。2つめの[]の中に0-9を追加です
08188152011/11/30(水) 01:10:35.02
ファイル名の最後の数字と分けたいってことでいいのかなぁ。それなら

^(.*?)(\\d+)\\.txt$

で$1と$2に入る。これは検索対象がファイル名であることを前提にしてる書き方だけどね。
これじゃだめなら何が足りないのか書いてね。
0819デフォルトの名無しさん2011/11/30(水) 01:50:36.80
>>812
アンカーにはさまざまなパターンが存在し、>>813氏も心配しているような誤反応の可能性がありますが、
シンプル版でよければ。

===
変換対象
(?<=\n)>>([1-9]\d{0,3})(?=[  ])
変換結果
レス$1へ返事
===
アンカーが行頭に存在し、かつ、
アンカーの後ろにスペースが入っている(SoftalkWEBの仕様)場合に置換します。

以下のように、番号を複数指定している場合などには未だ対応できていません。
>>1,2
>>1-2
また、>>1みたいな全角文字にも対応していません。

他のSoftalkWEBユーザの参考になるし、機能追加の要望にもなるので、
SoftTalkのサポート掲示板の方に投稿したほうが良いと思いますが、、、
0820デフォルトの名無しさん2011/11/30(水) 02:39:22.37
janeの引用行着色の正規表現を使いまわせそう。
http://www42.tok2.com/home/proxo/rep/src/rs0033.rep
0821デフォルトの名無しさん2011/11/30(水) 12:52:36.20
aの4回以上8回以下の繰り返し「 ^a{4,8}$ 」
ではなくて、
「aの4回または8回の繰り返し」
を ^(a{4}|a{8})$ のように「a」を2回使用せずに、「a」を1回だけ使用して指定する方法を教えてください。
0822デフォルトの名無しさん2011/11/30(水) 13:04:10.09
^(a{4}){1,2}$
08238212011/11/30(水) 14:36:25.94
>>822
ありがとうございます
0824デフォルトの名無しさん2011/11/30(水) 16:21:29.66
^(a)\1\1\1(\1\1\1\1)?$
0825デフォルトの名無しさん2011/11/30(水) 16:58:17.47
^((a)\2{3}){1,2}$
0826デフォルトの名無しさん2011/11/30(水) 20:26:15.49
質問です。

性器の生気を正規表現でどうしましょうか?
0827デフォルトの名無しさん2011/11/30(水) 23:04:22.59
^(a{4})\1?$
0828デフォルトの名無しさん2011/12/01(木) 09:28:19.54
PHP Version 5.2.9
preg_matchです。

電話番号の認証として、
/^\d[\d\-]+\d$/D
を使用していますが、
「1--3」のようなハイフン記号が続く場合の入力を許可してしまっています。

要件として、厳密な電話番号ルールは必要ではありません。
データとして「1-2-3」などを許可しています。

よろしくお願いいたします。
0829デフォルトの名無しさん2011/12/01(木) 10:43:50.07
^\d+-\d+-\d+$
0830デフォルトの名無しさん2011/12/01(木) 12:25:11.03
^(\d+-){2}\d+$
0831デフォルトの名無しさん2011/12/01(木) 13:00:55.38
>>829
素直に書けばそういう感じですね。
目からウロコです。
0832デフォルトの名無しさん2011/12/01(木) 13:22:51.62
目からウンコ?
0833デフォルトの名無しさん2011/12/01(木) 13:29:59.33
>>830
こちらを使用します。
ありがとうございます。
0834デフォルトの名無しさん2011/12/01(木) 14:36:15.33
正規表現は短ければいいってものじゃないからな、一応。短く書いたほうが処理が重くなるケースは多々ある。
08358142011/12/01(木) 15:05:13.05
>>815
アク禁で遅くなりました
ありがとう
0836デフォルトの名無しさん2011/12/01(木) 21:01:27.69
asdfg =~ /a|s|d|f|g/
こういうのが一番はやい。/(a-z)/より早い。でもめんどくさい。
0837デフォルトの名無しさん2011/12/03(土) 20:22:32.94
こ う い う 風 に ス ペ ー ス を 間 に 何 度 も 挟 む
ケ ー ス を 正 規 表 現 で や る と ど う す れ ば い い の か な
0838デフォルトの名無しさん2011/12/03(土) 20:28:51.44
マッチさせたいってこと?
([^ ] )+
0839デフォルトの名無しさん2011/12/03(土) 20:34:55.37
あ、なるほど!
0840デフォルトの名無しさん2011/12/03(土) 23:12:53.30
おい!!次スレがこの有様なのか?
http://hibari.2ch.net/test/read.cgi/tech/1322908056/l50
0841デフォルトの名無しさん2011/12/05(月) 16:10:59.60
●正規表現の使用環境
C#

●検索か置換か?
検索して、マッチしたものをキャプチャして置換したい。

●説明
文字列の演算式の項をキャプチャして置換したい。
演算子には、+,*,()のみが使用可能。括弧の入れ子も可能。

●対象データ(ex.)
(aaa+bbb)*(ccc+ddd)
があったとき、まず、aaa,bbb,ccc,dddをキャプチャして、
文字列変換(別途用意済)をする。
次に、それぞれ変換した文字列を元の式に戻す。
例えば、文字列変換が小文字⇒大文字への変換だった場合、
(AAA+BBB)*(CCC+DDD)
としてたい。
実際には、
string strBefore = "aaa";
string strAfter = 変換メソッド(strBefore);
という感じで、独自の変換メソッドを用意しています。

aaa*(bbb+ccc) ⇒ AAA*(BBB+CCC)
aaa*((bbb+ccc)+ddd) ⇒ AAA*((BBB+CCC)+DDD)
0842デフォルトの名無しさん2011/12/05(月) 16:45:57.87
正規表現使う必要無くね?
0843デフォルトの名無しさん2011/12/05(月) 17:15:20.40
ただのstrupr処理だわなw
08448412011/12/05(月) 17:27:54.69
>>843
struprはあくまで例です。
ここで複雑な変換処理の式を出しても混乱するだけだと思ったのでupperを出しただけです。
>実際には、
>string strBefore = "aaa";
>string strAfter = 変換メソッド(strBefore);
>という感じで、独自の変換メソッドを用意しています。
ここで事情は説明したつもりなのですが・・・
0845デフォルトの名無しさん2011/12/05(月) 17:42:16.92
ふつう正規表現でやるのは項の定義止まりだよ
0846デフォルトの名無しさん2011/12/05(月) 17:46:12.47
説明を簡略化しすぎても混乱してしまうよ。それと求めているのは正規表現そのものではなくて
正規表現のサンプルコードか何かのような気がするのだが・・。
08478412011/12/05(月) 18:16:25.27
>>846
すみません、たしかにロジックの説明は余計だった気がします。
教えて頂きたい正規表現は、四則演算「っぽい」文字列にマッチするかどうかというものです。
マッチさえすれば、あとはキャプチャして置き換えればよいとの認識です。

宜しくお願い致します。
0848デフォルトの名無しさん2011/12/05(月) 18:31:39.00
もとの制限を考えれば、+,*,() 以外の文字の連続がほしいものなんじゃないの?
0849デフォルトの名無しさん2011/12/05(月) 22:23:58.80
>>844
文字列の中に式らしき部分があって、その要素(項)を別に定義した約束事で
置換するというのでいいのかな。
0850デフォルトの名無しさん2011/12/05(月) 22:50:20.98
>>842は>>843的な意味で書いたのではなく、文字列操作関数だけでも出来るんじゃないかと思ったので書いた。
正規表現でやったほうが楽だけどね、処理速度は遅いけど。

・項にはどんな文字が使われるのか、英字だけなのか、ひらがなや漢字、数字なども含まれるのか 例、時間*時給
 (これがはっきりしないと書きようが無い)
・式の前後には改行は入っているのかいないのか
・全角文字には対応するのかしないのか 例、F+G

これらが分かれば簡単に書けるから誰かしらが作ってくれると思うよ。
0851デフォルトの名無しさん2011/12/05(月) 22:54:13.82
あ、括弧の入れ子を厳密に判定しようと思ったら普通の正規表現では無理。鬼車っていうライブラリを使ってるなら
簡単に対応出来る。鬼車でない場合は文字列操作関数で頑張ったほうが正確に判定出来ていいかも。
0852デフォルトの名無しさん2011/12/05(月) 23:07:39.25
使われる全ての文字の連続を検出すれば良い。
括弧が正確に対応するかは個別にCheck。正規表現使わなくていい。
0853デフォルトの名無しさん2011/12/05(月) 23:07:41.69
>>851
括弧の入れ子とか別に関係ないじゃん?
0854デフォルトの名無しさん2011/12/05(月) 23:23:12.62
>>853
((((aaa+bbb)*ccc(ddd)

こういう括弧の数が合わないものは式でない可能性が高い。それを置換してしまってもいいのかな?
0855デフォルトの名無しさん2011/12/05(月) 23:35:58.54
>>854
それを考慮するってことは、式の始まりまたは終わりを判断するつもりがあるということか。
0856デフォルトの名無しさん2011/12/05(月) 23:44:00.41
それをしなかったら正規表現使う意味なくない?
0857デフォルトの名無しさん2011/12/06(火) 02:48:57.24
だから正規表現いらなくねって意見がでてんでしょ
0858デフォルトの名無しさん2011/12/06(火) 06:28:53.19
括弧の入れ子の判定は正規表現でやったほうが断然楽だわな。いらないと思う人はこれが出来ない人なんだろう。
08598412011/12/06(火) 08:54:43.49
>>850
ご指摘ありがとうございます。

項はある検索エンジンで使用する独自の式が入ります。
"TERM"という定数に項を表す正規表現が記述されている、として頂ければと思います。
const string TERM = "●●"//●●←項を表す正規表現

式の前後に改行は入りません。
全角文字は、項の中ではありますが、+、*、(、)は半角のみを許可します。

よろしくおねがいします。
0860デフォルトの名無しさん2011/12/06(火) 09:23:04.74
難しい問題の合間に箸休めでお答えください
数字の入っているファイル名を置換したいです。

あああいいい01.txt
AABB0002.txt
なむなむ003.txt
TYTY4.txt
    ↓
THX001.txt
THX002.txt
THX003.txt
THX004.txt

.+(\d)(\d?)(\d?)(\d?)\.txt
などと、いろいろ試してはみたんですがうまくいきません。
どうかお力添えのほどをよろしくお願いします
0861デフォルトの名無しさん2011/12/06(火) 11:33:14.28
>>860
.+(\d)+\.txt

こういうこと?
0862デフォルトの名無しさん2011/12/06(火) 11:43:15.81
>>851
鬼車つかって簡単に対応したのを書いてもらえますか
08638602011/12/06(火) 17:48:58.84
>>861
レスありがとうございます。
条件をもう少しちゃんと書けばよかったですね
数字部分が0255などの時うまく置換できないのです。
数字部分だけで言うと、001,002,・・,255,・・880
のような形で置換したいです。
置換の方への記述の仕方もよくわからず、できればそちらもお願いいたします
0864デフォルトの名無しさん2011/12/06(火) 18:02:07.72
>>863
>>4
08658602011/12/06(火) 18:28:08.59
>>864 失礼しました

●正規表現の使用環境
psstpsstというリネームソフト(Perl互換)

●検索か置換か?
置換

●説明
最大4桁で書かれた数字部分を3桁に統一したい

●対象データ
ABCA01.txt
BCAA2.txt
CABA0255.txt

●希望する結果
AAA001.txt
AAA002.txt
AAA255.txt

どうぞよろしくおねがいします
0866デフォルトの名無しさん2011/12/06(火) 20:38:24.42
数字部分を3桁以上にしてから
(\d+\.)
000\1

下3桁だけ切り出し
\d*(\d{3}\..*)
\1
0867デフォルトの名無しさん2011/12/06(火) 22:41:35.61
>>841のは再帰を理解できるような拡張した正規表現を使えないとダメだろ。
そんなのあるのか。
0868デフォルトの名無しさん2011/12/06(火) 22:48:48.50
PCREは無限の括弧の対応が取れる ~ 再帰も、ネストも、あるんだよ.
http://swatmac.info/?p=716

正規表現の限界 @ Shibuya.pm
http://swatmac.info/etc/shibuya_pm/pix/recursive-regex.png
http://swatmac.info/etc/shibuya_pm/
0869デフォルトの名無しさん2011/12/06(火) 23:22:37.09
で、再帰が使えると>>854が懸念するようなことも解決できるの?
0870デフォルトの名無しさん2011/12/06(火) 23:35:32.29
理解してないができるはずだろ。マッチしないとき、括弧が足らないなどのエラーが判明する。


再帰的パターン
どうすればカッコに括られた文字列とマッチできるか、という問題を 考えて見ましょう。
このとき、カッコは何回でもネストできるとします。
再帰が使えないとすると、パターンを用いて、せいぜい、ある一定の深さの ネストまでしかマッチできないでしょう。
任意の深さのネストを 処理することは不可能です。
Perl 5.6 では、正規表現において再帰を行う 実験的な機能が導入されています。
PCRE では、再帰という特殊なケースに対して専用のシーケンス (?R) が導入されました。
http://php.net/manual/ja/regexp.reference.recursive.php
0871デフォルトの名無しさん2011/12/06(火) 23:46:03.39
出来るよ、このスレでこんな認知度低いほうが意外なくらい。
0872デフォルトの名無しさん2011/12/06(火) 23:58:07.19
windowsで手軽にpeclの動作確認する方法ありますか。
0873デフォルトの名無しさん2011/12/07(水) 00:00:50.43
xampp入れてPHPですかね。
0874デフォルトの名無しさん2011/12/07(水) 00:03:36.96
認知度の話じゃなくて、項には全角も含まれるといわれている状態で、再帰でできるとか言ってるのが斜めってることに気づかないのかな。

「たとえばほげほげ+fooという文字列」
↑この中の項をどうやって判別するの。
0875デフォルトの名無しさん2011/12/07(水) 00:07:35.69
全角や、英数のみはたいした問題でない。
どの文字を許可するかはそのつど変わる。
0876デフォルトの名無しさん2011/12/07(水) 00:12:27.18
だから現状ではできない、でおk?
0877デフォルトの名無しさん2011/12/07(水) 00:18:13.56
なんでよ?
文字コードの問題があるけど、たとえばUTF32などだったら英数も全角も同じバイト長で区別はない。
0878デフォルトの名無しさん2011/12/07(水) 00:23:06.12
>>877
>>855でも書いたけど、式の始まりと終わり、項と項以外をどうやって判断するの?

体重+年齢と性別*5
このとき、何が項として抽出されるべきかを書いてみ?
べつに>>874でもいいけど。
0879デフォルトの名無しさん2011/12/07(水) 00:25:53.18
項に使える文字はあらかじめ指定するんだろ。
たとえば[0-9a-z]としてあとで変更することもできる。
全角になったとしてもたいした問題でない。
0880デフォルトの名無しさん2011/12/07(水) 00:26:54.45
>>878

こうわけるのが普通だろ。他にどう分けるんだよ。

体重  +  年齢と性別  *  5
0881デフォルトの名無しさん2011/12/07(水) 00:29:23.51
対象文字列が式のみかどうかなんて書いてないよな。
0882デフォルトの名無しさん2011/12/07(水) 00:31:54.36
対象文字列が式のみであるという前提を勝手につけるなら、わざわざ括弧の整合性チェックをする必要なんてないよな。
0883デフォルトの名無しさん2011/12/07(水) 01:05:10.14
>>882
いつまで雑魚の相手をするつもりなんだ?
0884デフォルトの名無しさん2011/12/07(水) 01:12:28.09
>>841
正規表現はマッチするだけ。置換処理はプログラミングの分野。はき違えてはいけない。
http://ideone.com/2xlKW
0885デフォルトの名無しさん2011/12/07(水) 01:24:06.45
項の部分は質問者さんが正規表現を作るのかな、>>859を読むとこう取れなくもないのだが。
>>850で「はっきりしないと書きようがない」と言われてるのにはっきりさせないから混乱するんだ。
0886デフォルトの名無しさん2011/12/07(水) 01:53:13.54
項は仮に[a-z0-9]でいいだろ。
0887デフォルトの名無しさん2011/12/07(水) 04:54:20.90
>>884
そんな手間かけてゴミレス付けんなよ。
08888602011/12/07(水) 10:11:04.84
>>866
実はその発想はあったのですが、下3桁の切り出し方が分かっておりませんでした。
どうもありがとうございました。

また、もし一工程で済ます方法があったとしたら
後学のために教えていただけると幸いです
0889デフォルトの名無しさん2011/12/07(水) 13:40:04.24
>>888
参考に...
このスレの範疇を超えちゃってアレだけど、
Flexible Renamerっていうリネームソフトなら正規表現+スクリプトを使って一発でできるみたい
検索:.+?(\d+)(\.[^\.]+)$
置換:"AAA"+right("00\1",3)+"\2"
(高度なリネーム、正規表現、スクリプトにチェック)
0890デフォルトの名無しさん2011/12/07(水) 15:53:09.38
高度な置換をしたい場合はどうしてもプログラムコードが必要になるけどそれを提供してるツールもあるんだね、
08918602011/12/07(水) 16:20:58.95
>>889 おおー!完璧です!
FlexibleRenamerはちょっと重いので敬遠していたのですが
スクリプトとの合わせ技が使えるんですね
自分には少しハードルが高いですけど
rightってことは・・・左からはleftとか使えるんだろうな〜と想像したり
"right(00\1,3)"ではないのがいまひとつ分からなかったりしますが
大変勉強になりました。ありがとうございます
0892デフォルトの名無しさん2011/12/07(水) 16:29:14.42
元々数字が4桁以上あったら上の桁を切り捨てちゃうけどそれでいいのかな・・自分ならこれを防ぐ処理も入れるな。
それと拡張子なしのファイルには対応出来ないけどこれは考えなくても良いのかな。
0893デフォルトの名無しさん2011/12/07(水) 16:31:05.75
スレチだけど、Flexible Renamerは便利だね。
練馬ってのもいろいろできるけど、こっちはややこしいイメージを受けると思う。
0894デフォルトの名無しさん2011/12/07(水) 16:32:29.05
もともと4桁は想定してるようだよ。
ただ、雰囲気的に、4桁の場合は先頭が0であるという暗黙の条件があるんだろうと思ってる。
拡張子も然り。
0895デフォルトの名無しさん2011/12/07(水) 16:35:20.55
>>894
実用的に問題無いならいいんだけどね。
0896デフォルトの名無しさん2011/12/07(水) 16:42:08.49
まあ、4桁を使うようなデータが出てきたら今回のを改変して、そのまま流せばいいってのもあるとおもう
0897デフォルトの名無しさん2011/12/08(木) 00:57:46.56
>>886
こう仮定して再帰を使った正規表現作ってくれる人ってこのスレにいるの?いない気がする。
0898デフォルトの名無しさん2011/12/08(木) 00:58:40.07
正規表現を作ってあげたとしても質問者がコードを組めるかという問題もあるね。
0899デフォルトの名無しさん2011/12/08(木) 01:07:07.26
>>897
「正規表現で何をしたいのかと細かい条件」

これを質問者がしっかり文章化して投下してくれないと始まらないね
0900デフォルトの名無しさん2011/12/08(木) 02:48:45.53
>>899
それがあいまいな状態で「エンジンが鬼車なら再帰でできる」なんていうのがいるから困るんよ
0901デフォルトの名無しさん2011/12/08(木) 03:43:54.44
嫉妬か。
0902デフォルトの名無しさん2011/12/08(木) 05:08:31.56
斜めにもほどがあるだろ
0903デフォルトの名無しさん2011/12/08(木) 05:16:39.14
>>900=>>874=>>902か、嫉妬乙。
0904デフォルトの名無しさん2011/12/08(木) 05:26:48.85
おしい
0905デフォルトの名無しさん2011/12/08(木) 05:43:03.37
俺も鬼車だと簡単に書けるっていうから回答楽しみにしてる
09068602011/12/08(木) 06:52:42.57
>>892-896
みなさんありがとうございます
>>894さんの仰る通り4桁とはいっても先頭は0です。
全部で800くらいのものを10人ばかりで分担作業したので、人それぞれでファイル名が・・・となりまして

今回のを参考に、複雑な処理はFlexibleRenamerも使ってみようと思います。
まだ消化しきれてない部分もあるので、少しずつですが勉強していきます。
どうもありがとうございました
09078412011/12/08(木) 08:42:06.05
>>874
>>878
たとえばほげほげ+fooという文字列 ⇒項は「たとえばほげほげ」と「fooという文字列」
体重+年齢と性別*5  ⇒ 項は「体重」と「年齢と性別」と「5」
です。

>>899
正規表現でやりたいことは、
・'+','*','(',')'の4つの演算子と、C_TERMで定義された項を使った式がマッチするかどうかを判断したい。
・スレ内で議論されている、()の対応も処理したい。※(1+1))*2は当然アンマッチ
・四則演算といっていますが、項は数字ではなく、ただの文字列なので、取り出せればOKです。
・で、(?<TERM>C_TERM)を使って、マッチした項を取り出し、Match.replace()で
 項を変換して置き換える。(この辺はC#の処理系の話ですが。)

また、C_TERMで使える文字使えない文字は別途チェックをします。
当然、+、*、(、)は項の文字としては使えません。
0908デフォルトの名無しさん2011/12/08(木) 11:26:21.12
>>907
項を取り出すだけなら [^+-()]+ で十分でしょう
演算子の処理も含めるなら演算子にもマッチさせる必要があるでしょうね [^+-()]+│[\s\S]
処理をどうするかは正規表現の範疇ではありません
レス数が900を超えています。1000を超えると表示できなくなるよ。