C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: 正規表現


(過去ログ 53 を表示中)

[トピック内 27 記事 (1 - 20 表示)]  << 0 | 1 >>

■29481 / inTopicNo.1)  正規表現
  
□投稿者/ ヤンサン (1回)-(2008/12/10(Wed) 11:30:28)

分類:[C#] 

2008/12/10(Wed) 12:01:22 編集(投稿者)

以下の条件の正規表現を作りたいのですがイマイチよくわかりません。

『-1000〜1000 の数字で、その間なら小数も可(小数点第2位まで)』
※0は良いが0から始まるひとケタ以上の数字002などは不可です。-0も不可。
※マイナスが数字の間に入る、1-1などは不可です。
※小数点が先頭に付く.125などは不可です。

取りあえず条件はこんなところです。
(@"^[0-9]+$")←こういう感じでお答えいただければ幸いです。
どなたかご教授お願いします。

引用返信 編集キー/
■29484 / inTopicNo.2)  Re[1]: 正規表現
□投稿者/ .SHO (353回)-(2008/12/10(Wed) 11:33:09)
No29481 (ヤンサン さん) に返信

> 『-1000 <= 0 <= 1000 の数字

って、ようするに -1000 〜 1000 ってことですか?
引用返信 編集キー/
■29486 / inTopicNo.3)  Re[1]: 正規表現
□投稿者/ 倉田 有大 (388回)-(2008/12/10(Wed) 11:41:05)
No29481 (ヤンサン さん) に返信
> 2008/12/10(Wed) 11:31:47 編集(投稿者)
>
> 以下の条件の正規表現を作りたいのですがイマイチよくわかりません。
>
> 『-1000 <= 0 <= 1000 の数字で、その間なら少数も可(小数点第2位まで)』
> ※0は良いが0から始まるひとケタ以上の数字002などは不可です。-0も不可。
> ※マイナスが数字の間に入る、1-1などは不可です。
> ※小数点が先頭に付く.125などは不可です。
>
> 取りあえず条件はこんなところです。
> (@"^[0-9]+$")←こういう感じでお答えいただければ幸いです。
> どなたかご教授お願いします。

うーん、100-100の場合100だけ欲しくて、100 -100の場合は100と-100が欲しいという意味ですか?
いまいち検索元のテキストがどんなのか想像がつきません〜
引用返信 編集キー/
■29492 / inTopicNo.4)  Re[2]: 正規表現
□投稿者/ ヤンサン (3回)-(2008/12/10(Wed) 11:57:52)
No29486 (倉田 有大 さん) に返信

そのような複雑なことは考えておりません;;
100-100の場合は不一致となればいいです。


書き方が悪かったですね、、
-1000〜1000で小数は小数点第2位までってことです。

ヤンサン
引用返信 編集キー/
■29497 / inTopicNo.5)  Re[3]: 正規表現
□投稿者/ .SHO (356回)-(2008/12/10(Wed) 12:21:59)
No29492 (ヤンサン さん) に返信

「-」と「NNNN」と「.」と「NN」に分割して
それぞれを正規表現で表現してくっつければいいです。

ただし、002 や -0 は正規表現では無理なので
正規表現を通ったあとに、double に Parse してから
文字列に戻して比較すればいいと思います。

引用返信 編集キー/
■29502 / inTopicNo.6)  Re[4]: 正規表現
□投稿者/ ヤンサン (4回)-(2008/12/10(Wed) 12:29:44)
No29497 (.SHO さん) に返信

具体的な実装例を教えていただくわけにはいきませんでしょうか?
引用返信 編集キー/
■29516 / inTopicNo.7)  Re[5]: 正規表現
□投稿者/ .SHO (361回)-(2008/12/10(Wed) 13:01:48)
No29502 (ヤンサン さん) に返信

> 具体的な実装例を教えていただくわけにはいきませんでしょうか?

@"^-?[0-9]{4}.[0-9]{2}"
引用返信 編集キー/
■29517 / inTopicNo.8)  Re[6]: 正規表現
□投稿者/ .SHO (362回)-(2008/12/10(Wed) 13:04:14)
間違えた。。。

(@"^-?[0-9]{1,4}.[0-9]{0,2}")
引用返信 編集キー/
■29532 / inTopicNo.9)  Re[7]: 正規表現
□投稿者/ ヤンサン (6回)-(2008/12/10(Wed) 14:07:01)
No29517 (.SHO さん) に返信

回答ありがとうございます。

しかし、教えていただいたものでは出来ていませんでした。
下記に書くのは、したいことのうち出来ていなかったことのうち私が気付いた点です。

@整数一桁のみ例えば8などは一致となりません
A2桁以上ならどんな整数も一致となる。たとえば55555555555555も一致となる。
B小数も同様で、何けたになっても一致となる。たとえば5.555555555555も一致となる。
Cマイナスが数字の間に入る、1-1なども一致となる。

今のところ気づいたのはこれ位ですが、
全然希望するものとは違っています;;

ヤンサン

引用返信 編集キー/
■29535 / inTopicNo.10)  Re[8]: 正規表現
□投稿者/ .SHO (363回)-(2008/12/10(Wed) 14:36:12)
No29532 (ヤンサン さん) に返信

( @"^-?[0-9]{1,4}\.?[0-9]{0,2}$" )
引用返信 編集キー/
■29536 / inTopicNo.11)  Re[3]: 正規表現
□投稿者/ よねKEN (222回)-(2008/12/10(Wed) 14:39:16)
> -1000〜1000で小数は小数点第2位までってことです。

・テストは不十分です。
・十分吟味した正規表現ではないので、整理すればもっとコンパクトで
 わかりやすいものになる・・・かもしません。
・小数第三位以降に入力がある場合もマッチしないようにしています。

正規表現は得意ではないので、もっとコンパクトに書く方法もあるかもしれませんが、
私ならこんな正規表現は使いたくないです。

正規表現で扱うのはチェックしたい内容の一部にしますね。
少なくとも数値範囲のチェックは別にやるようにして、-0や002などは自動で0や2に変換する
ような方法を取ると思います。  

private void TestAll()
{
    string s = 
        @"^(-?(1000(\.0{1,2})?|[1-9][0-9]{0,2}(\.[0-9]{1,2})?|0\.([1-9][0-9]|[0-9][1-9]))|0(\.0{1,2})?)$";
    Regex r = new Regex(s);
    object[,] tests = new object[,]{
        {"1000.00", true},
        {"1000.01", false},
        {"1000.000", false},
        {"-1000.00", true},
        {"-1000.01", false},
        {"-1000.000", false},
        {"0", true},
        {"0.0", true},
        {"-0", false},
        {"-0.0", false},
        {"009", false},
        {"1001", false}
    };

    for (int i = 0; i < tests.GetUpperBound(0); i++)
    {
        Debug.WriteLine(
            String.Format(
                "テストする値:{0} 想定される結果:{1} → テスト結果:{2}",
                tests[i, 0],
                (bool)tests[i, 1] ? "マッチする" : "マッチしない",
                Test(r, (string)tests[i, 0], (bool)tests[i, 1]) ? "OK" : "NG"
            )
        );
    }
}

private bool Test(Regex r, string input, bool ans)
{
    return (r.IsMatch(input) == ans);
}

引用返信 編集キー/
■29537 / inTopicNo.12)  Re[9]: 正規表現
□投稿者/ ヤンサン (7回)-(2008/12/10(Wed) 14:45:43)
No29535 (.SHO さん) に返信

返答ありがとうございます。

まだ少々問題点があるようです。
@5桁や6桁の整数が一致となる。
A1000より大きい数や-1000より小さい数も一致となる。

また、002 や -0 の正規表現を通ったあとに、
double に Parse してから文字列に戻して比較の方法も教えていただけませんでしょうか?
引用返信 編集キー/
■29538 / inTopicNo.13)  Re[10]: 正規表現
□投稿者/ ヤンサン (8回)-(2008/12/10(Wed) 14:49:00)
No29537 (よねKEN さん) に返信

ありがとうございます。
検証後また、連絡します。
引用返信 編集キー/
■29539 / inTopicNo.14)  Re[10]: 正規表現
□投稿者/ みきぬ (287回)-(2008/12/10(Wed) 14:52:26)
正規表現を使わない方法(脳内のみ・未検証)

・とりあえず decimal に Parse してみる → できなかったら NG
・decimal に Parse したものを ToString() して、元の文字列と比較 → 異なっていたら NG
・decimal に Parse したものを 100 倍して、-100000 以上 100000 以下の整数だったら OK

引用返信 編集キー/
■29541 / inTopicNo.15)  Re[10]: 正規表現
□投稿者/ .SHO (364回)-(2008/12/10(Wed) 14:57:10)
No29537 (ヤンサン さん) に返信

> @5桁や6桁の整数が一致となる。
> A1000より大きい数や-1000より小さい数も一致となる。

無理です。

そもそも、正規表現は文字列を比較するものであって
数値を比較するものではないです。

-1000〜1000の数値範囲のチェックはdoubleに変換してから
範囲チェックしてください。
これにより必然的@も排除されます。

引用返信 編集キー/
■29553 / inTopicNo.16)  Re[11]: 正規表現
□投稿者/ ヤンサン (9回)-(2008/12/10(Wed) 16:41:15)
よねKEN が教えてくれた方法で無事できました!
ありがとうございます。

しかし、
(@"^(-?(1000(\.0{1,2})?|[1-9][0-9]{0,2}(\.[0-9]{1,2})?|0\.([1-9][0-9]|[0-9][1-9]))|0(\.0{1,2})?)$");
という正規表現なんですが、ちょっと難解で理解できません;;
解説をお願いすることはできませんでしょうか?
引用返信 編集キー/
■29558 / inTopicNo.17)  Re[12]: 正規表現
□投稿者/ よねKEN (223回)-(2008/12/10(Wed) 17:14:09)
2008/12/10(Wed) 17:25:26 編集(投稿者)

No29553 (ヤンサン さん) に返信
> よねKEN が教えてくれた方法で無事できました!

回答しておいてなんですが、仕事で使うプログラムであれば、
この実現方法を使うのは基本的に避けてください。
提示の方法は、-1000〜1000に限定された書き方なので、値の範囲が動的に変わるような場合や、
今は-1000〜1000でも将来的に変更になる可能性がある場合に破綻します。
(毎度毎度プログラム修正&テストが必要になります)

> (@"^(-?(1000(\.0{1,2})?|[1-9][0-9]{0,2}(\.[0-9]{1,2})?|0\.([1-9][0-9]|[0-9][1-9]))|0(\.0{1,2})?)$");
> という正規表現なんですが、ちょっと難解で理解できません;;
> 解説をお願いすることはできませんでしょうか?

(1) マイナス符号を付けてよい場合と付けてはダメな場合がある。
  →@"^(-?<マイナス符号を付けてよい値の正規表現>|<マイナス符号を付けてはダメな値の正規表現>)$"
(2) -1000〜1000の範囲ということは、絶対値で言うと1000以下の範囲。
 最大値は1000、1000.0、1000.00のいずれか。
  →1000(\.0{1,2})?
(3) 4桁の整数は1000だけなので、(2)で考慮済み。
  よって、後は整数部3桁以下の値のみを考慮すればよい。
  →[1-9][0-9]{0,2}(\.[0-9]{1,2})?
   → 前半の[1-9][0-9]{0,2} は1〜999の値だけに制限しています。最上位桁の部分を[1-9]と
     することで0を除外し、002みたいなパターンをはじきます。
     後半の(\.[0-9]{1,2})?が最大2桁の小数部(省略可能)です。
(4) 0.0、0.00以外の整数部0の小数はOK
  小数部2桁のどちらかで0以外の数字が含まれていればよい。
  → 0\.([1-9][0-9]|[0-9][1-9])
(5)0は-を付けられないが、それ以外の値は-を付けられる。
 0、0.0、0.00はマイナス符号を付けてはいけないパターン。
  → 0(\.0{1,2})?

※(1)の<マイナス符号を付けてよい値の正規表現>と書いている部分は(2)または(3)または(4)で、
 (1)の<マイナス符号を付けてはダメな値の正規表現>が(5)です。

引用返信 編集キー/
■29560 / inTopicNo.18)  Re[13]: 正規表現
□投稿者/ ヤンサン (10回)-(2008/12/10(Wed) 17:33:30)
No29558 (よねKEN さん) に返信

丁寧な解説ありがとうございます。

この実現方法を使うのは基本的に避けたほうが良いとありますが、
では、よねKENさんが作るとしたらどういう風に実装されますか?
といいますか、どのようにしたら仕様変更に強くなりますか?



引用返信 編集キー/
■29565 / inTopicNo.19)  Re[14]: 正規表現
□投稿者/ くだん (11回)-(2008/12/10(Wed) 17:59:26)
No29560 (ヤンサン さん) に返信
> どのようにしたら仕様変更に強くなりますか?
すでに指摘を受けてるでしょう?
>正規表現を使わない
>double に Parse
>ToString() して、元の文字列と比較 → 異なっていたら NG
などなど。
引用返信 編集キー/
■29567 / inTopicNo.20)  Re[14]: 正規表現
 
□投稿者/ .SHO (369回)-(2008/12/10(Wed) 18:00:46)
No29560 (ヤンサン さん) に返信

> といいますか、どのようにしたら仕様変更に強くなりますか?

既に沢山、答えが出てます。
引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -