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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.85005 の関連記事表示

<< 0 | 1 >>
■85005  正規表現の考え方がわかりません
□投稿者/ 夜叉丸 -(2017/09/05(Tue) 09:40:09)

    分類:[.NET 全般] 

    正規表現の考え方を教えてください

    ra.ToString() = "{X=3, Y=6, Width=9, Height=12}"
    Match m = new Regex(@"{X=(?<X>[-]*\d+),Y=(?<Y>[-]*\d+),Width=(?<Width>[-]*\d+),Height=(?<Height>[-]*\d+)}").Match(ra.ToString());
    int ix = (int.TryParse(m.Groups["X"].ToString(), out ix)) ? ix : 0;

    この場合
    "3" = "(?<X>[-]*\d+)" であらわされるということですよね。

    ?<X> でグループを表す
    [-] 連続した文字範囲の1文字 : あるかもしれないしないかもしれないマイナスフラグ
    * 直前の文字が0回以上繰り返す。 : なので先頭だから繰り返さないので0回以上?
    \d 0から9までの数字       : 数字を使用
    + 直前の文字が1回以上繰り返す。 : 数字が連続する

    で認識しました。
    ところが同様にfloat の場合どうすればよいのかわかりません。

    raf.ToString() = "{X=3.1, Y=6.2, Width=9.3, Height=12.4}"

    "?<X>[-]*\d+" ここまではそのまま使えばよいと思いますが

    .はあるかもしれないしないかもしれないので [.] を使いました。"?<X>[-]*\d+[.]"
    次に来るのは数字ですが、前に '.' があるかもしれないので 直前の文字が0回以上繰り返すを使用して
    "?<X>[-]*\d+[.]*\d"
    としたのですがだめでした。

    また、.も文字だからとして
    (?<X>[-]*\w+)
    これもだめでした。

    正規表現の考え方が全く分からないのですが
    どうすれば理解できるのでしょうか?
親記事 /過去ログ145より / 関連記事表示
削除チェック/

■85007  Re[1]: 正規表現の考え方がわかりません
□投稿者/ ペイビン -(2017/09/05(Tue) 10:05:09)
    [ ]の中のハイフン「-」って、[A-Z](AからZまでの文字にマッチ)のようにつかうものだと思っていましたが、
    [-]と書いてしまうと、ただの「-」にマッチするだけなのではないでしょうか?
    (違っていたらゴメンナサイ)
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85009  Re[2]: 正規表現の考え方がわかりません
□投稿者/ WebSurfer -(2017/09/05(Tue) 10:54:11)
    No85007 (ペイビン さん) に返信
    > [ ]の中のハイフン「-」って、[A-Z](AからZまでの文字にマッチ)のようにつかうものだと思っていましたが、
    > [-]と書いてしまうと、ただの「-」にマッチするだけなのではないでしょうか?


    上記の点については、以下の記事の「文字クラス」のセクションが参考になると思います。

    ASP.NET の正規表現
    https://msdn.microsoft.com/ja-jp/library/ms972966.aspx

    "ハイフン文字は、先頭の文字でない場合に限り、文字クラス内で特別な意味を持ちます"

    "範囲内にハイフンを含める必要がある場合は、それを先頭の文字として指定してください"
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85013  Re[2]: 正規表現の考え方がわかりません
□投稿者/ 夜叉丸 -(2017/09/05(Tue) 12:46:56)
    No85007 (ペイビン さん) に返信
    > [ ]の中のハイフン「-」って、[A-Z](AからZまでの文字にマッチ)のようにつかうものだと思っていましたが、
    > [-]と書いてしまうと、ただの「-」にマッチするだけなのではないでしょうか?
    > (違っていたらゴメンナサイ)

    私もそう思います。
    なので、マイナスがあれば マイナスをとってくるし、
    なければ何も取ってこないのだという認識だったのですが。
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85008  Re[1]: 正規表現の考え方がわかりません
□投稿者/ WebSurfer -(2017/09/05(Tue) 10:47:26)
    No85005 (夜叉丸 さん) に返信

    文字列の条件を明確にしていただかないとなかなかレスしずらいです。

    最初の例のパターン [-]*\d+ は、最初に '-' が 0 回以上の繰り返し、その次が数字
    の 1 回以上の繰り返しになりますが、そうすると例えば以下の入力にもマッチするは
    ずです。

    -----3
    00000000
    2147483648 (Int32.MaxValue を超える数字)

    そういう入力はダメなら、それにはマッチしないパターンを考える必要がありそうです。

    次のステップとして小数点を許可する場合も、同様に、マッチ条件を考える必要があると
    思うのですが。

    "1.0.0.0" などという入力までマッチさせていいのか、そういうのは入力として来ないの
    で考えなくていいのかでパターンが変わってくると思います。
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85014  Re[2]: 正規表現の考え方がわかりません
□投稿者/ 夜叉丸 -(2017/09/05(Tue) 12:49:24)
    No85008 (WebSurfer さん) に返信
    > ■No85005 (夜叉丸 さん) に返信
    >
    > 文字列の条件を明確にしていただかないとなかなかレスしずらいです。
    >
    最初は Rectangle ra です。
    Match m = new Regex(@"{X=(?<X>[-]*\d+),Y=(?<Y>[-]*\d+),Width=(?<Width>[-]*\d+),Height=(?<Height>[-]*\d+)}").Match(ra.ToString());
    これだと取得することができました。

    わからないのは RectangleF ra になります。
    0になってしまいます。
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85021  Re[3]: 正規表現の考え方がわかりません
□投稿者/ WebSurfer -(2017/09/05(Tue) 15:07:03)
    No85014 (夜叉丸 さん) に返信

    > 最初は Rectangle ra です。

    それを聞いているのではなく、正規表現の話なので、対象となる文字列がどうなるのか
    を聞いています。

    たぶん、Rectangle というのは System.Drawing.Rectangle 構造体のことで、ToString
    メソッドで得られる文字列を対象としているのでははないかと想像してます。

    Rectangle の方は X, Y, Width, Height いずれも Int32 型ということで、ToString が
    どういう結果になるかはたぶん想像の範囲に収まるでしょうけど、RectangleF の方はど
    うなるのでしょう?

    自分が探した限りですが、RectangleF.ToString() がどういう結果になるかを書いた
    Microsoft の公式文書見つかりませんでした。

    #MSDN ライブラリには "この Rectangle 構造体の位置、幅、および高さが含まれた文字
    列 (例 : {X=20, Y=20, Width=100, Height=50})" と書いてありましたが、そもそもそれ
    も間違っているし・・・

    なので、実際に試してその結果から想像するしかなさそうです。

    それを回答者が行うのではなく、質問者さんの方で調べて質問者さんの言葉で書いていた
    だきたかったのですが。
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85024  Re[3]: 正規表現の考え方がわかりません
□投稿者/ WebSurfer -(2017/09/05(Tue) 15:53:15)
    No85014 (夜叉丸 さん) に返信
    
    ちょっとだけ調べてみましたが、
    
    new RectangleF(20f, -20.856f, 100.123456789f, 50.9f);
     ↓↓
    {X=20,Y=-20.856,Width=100.1235,Height=50.9}
    
    という結果から、指数形式になることはない、数字として変な形(1.0.0 とか ---1 とか)
    になることはない・・・とすれば、数字のところは「ハイフン、数字、ピリオドが一文字
    以上」という条件のみでよさそうです。
    
    であれば、以下のようにしてできると思います。
    
    Rectangle re = new Rectangle(20, -20, 100, 50);
    Console.WriteLine(re.ToString());
    RectangleF rf = new RectangleF(20f, -20.856f, 100.123456789f, 50.9f);
    Console.WriteLine(rf.ToString());
    
    Regex regex = new Regex(@"
        ^                   # 開始のアンカー
        {X=                 # {X= という文字列で始まる 
        (?<X>[-0-9.]+)      # X という名前付グループ。ハイフン、数字、ピリオドが一文字以上
        ,Y=                 # ,Y= という文字列が来る
        (?<Y>[-0-9.]+)      # Y という名前付グループ。ハイフン、数字、ピリオドが一文字以上
        ,Width=             # ,Width= という文字列が来る
        (?<Width>[-0-9.]+)  # Width という名前付グループ。ハイフン、数字、ピリオドが一文字以上
        ,Height=            # ,Height= という文字列が来る
        (?<Height>[-0-9.]+) # Height という名前付グループ。ハイフン、数字、ピリオドが一文字以上
        }                   # } で終わる
        $                   # 終了のアンカー",
        RegexOptions.IgnorePatternWhitespace);
    
    Match m = regex.Match(re.ToString());
    GroupCollection g = m.Groups;
    Console.WriteLine("X=" + g["X"].Value + ",Y=" + g["Y"].Value + 
        ",Width=" + g["Width"].Value + ",Height=" + g["Height"].Value);
    
    m = regex.Match(rf.ToString());
    g = m.Groups;
    Console.WriteLine("X=" + g["X"].Value + ",Y=" + g["Y"].Value +
        ",Width=" + g["Width"].Value + ",Height=" + g["Height"].Value);
    
    /*
    結果は:
    {X=20,Y=-20,Width=100,Height=50}
    {X=20,Y=-20.856,Width=100.1235,Height=50.9}
    X=20,Y=-20,Width=100,Height=50
    X=20,Y=-20.856,Width=100.1235,Height=50.9
    */
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85025  Re[4]: 正規表現の考え方がわかりません
□投稿者/ Hongliang -(2017/09/05(Tue) 16:03:53)
    > という結果から、指数形式になることはない、数字として変な形(1.0.0 とか ---1 とか)
    > になることはない・・・とすれば、数字のところは「ハイフン、数字、ピリオドが一文字
    > 以上」という条件のみでよさそうです。

    指数形式になりえますし、NaNも正負の無限大も出現しえますよ。
    個々の浮動小数点数値はSingle::ToStringしてるだけですね。
    https://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Advanced/RectangleF.cs
    // CurrentCultureを使ってるので、小数点記号が "," の可能性とかも考える?
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85026  Re[5]: 正規表現の考え方がわかりません
□投稿者/ WebSurfer -(2017/09/05(Tue) 17:16:00)
    No85025 (Hongliang さん) に返信

    > 指数形式になりえますし、NaNも正負の無限大も出現しえますよ。
    > 個々の浮動小数点数値はSingle::ToStringしてるだけですね。

    > CurrentCultureを使ってるので、小数点記号が "," の可能性とかも考える?

    RectangleF 構造体に設定された X. Y, Width, Height を ToString するという場合は NaN や
    正負無限大は考えなくてもよさそうだと思いますが、指数は、

    RectangleF rf = new RectangleF(20f, -20.856f, 100.123456789f, .0000023f);

    というようなことをすると(実際にそういう設定が有るかどうかはさておき)、

    {X=20,Y=-20.856,Width=100.1235,Height=2.3E-06}

    になってしまいますね。

    小数点も fr-FR とかですと '.' ではなく ',' になるようですし。

    RectangleF.ToString に限れば、数字の部分の文字列を取得できれば良いわけで、どういう文
    字列になるかは気にする必要はないわけですから、確かに No85016 の Hongliang さんの案が
    現実的だと自分も思います。
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85028  Re[6]: 正規表現の考え方がわかりません
□投稿者/ 魔界の仮面弁士 -(2017/09/05(Tue) 18:47:55)
    No85026 (WebSurfer さん) に返信
    > ■No85025 (Hongliang さん) に返信
    > 確かに No85016 の Hongliang さんの案が現実的だと自分も思います。

    同じく一票。

    元の RectangleF.ToString で得た値が、小数表記でも指数表記でも非数値(NaN)や無限大でも
    float.Parse/.TryParse で問題なく復元できるので、コードも比較的単純になります。
    (ToString 時のカルチャと TryParse 時のカルチャを合致させる必要はありますが)


    <蛇足>
    Rectangle → String → Rectangle な変換が目的であれば、
    型コンバーター(RectangleConverter クラス)を使えないかと思ったのですが、
    ToString の場合とは書式が異なりますし、RectangleF には使えないので断念…。
    </蛇足>
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85128  Re[7]: 正規表現の考え方がわかりません
□投稿者/ 夜叉丸 -(2017/09/12(Tue) 11:49:52)
    No85028 (魔界の仮面弁士 さん) に返信
    > ■No85026 (WebSurfer さん) に返信
    >>■No85025 (Hongliang さん) に返信
    >>確かに No85016 の Hongliang さんの案が現実的だと自分も思います。
    >
    > 同じく一票。
    >

    X=(?<X>.+?) と X=(?<x>.+) は結果的に同じなのでしょうか?
    ? があるのとないのとでの違いが判りません。
    結果は同じのように見えますが

    最終的に
    X=???,Y=???,Width=???,Height=???
    にて、??? を取りたかっただけなので
    X=(?<X>.+?) や X=(?<x>.+) で取り込めました
    ??? は int または float の文字列なので
    float.Parse() でとれば 値は取得することが可能だと思います。
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85131  Re[8]: 正規表現の考え方がわかりません
□投稿者/ 魔界の仮面弁士 -(2017/09/12(Tue) 12:11:56)
    No85128 (夜叉丸 さん) に返信
    > X=(?<X>.+?) と X=(?<x>.+) は結果的に同じなのでしょうか?
    前者のグループ名は "X" ですが、
    後者のグループ名は "x" ですね。

    > ? があるのとないのとでの違いが判りません。
    (?<X>何某) の方の "?" だとしたら、グループ名をつけるためのものです。
    .+? の方の "?" だとしたら、最短一致を意味します。

    string text = "X=12,Y=34,Y=56,Z=78";
    var m1 = Regexes.Match(text, "Y=(?<y>.+?)");
    var m2 = Regexes.Match(text, "Y=(?<y>.+)");
    var m3 = Regexes.Match(text, "Y=(?<y>[^,]+)");


    たとえば上記の場合、下記の結果となります。

    m1[0].Groups["Y"].Captures[0].Value == "3"
    m1[1].Groups["Y"].Captures[0].Value == "5"
    m2[0].Groups["Y"].Captures[0].Value == "34,Y=56,Z=78"
    m3[0].Groups["Y"].Captures[0].Value == "34"
    m3[1].Groups["Y"].Captures[0].Value == "56"
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85030  Re[3]: 正規表現の考え方がわかりません
□投稿者/ WebSurfer -(2017/09/05(Tue) 19:27:28)
    No85014 (夜叉丸 さん) に返信

    Rectangle.ToString とか RectabgleF.ToString で得られた文字列から正規表現を使って X, Y, Width,
    Height を取り出す必要性があるかというと、.NET アプリの世界に限れば全く完全に 100% ないと思うの
    ですが・・・

    プロパティとして X, Y, Width, Height が提供されているのですから、それを使えばいいのですから。

    このような質問をしたのはどういう理由でしょう。教えていただけませんか? > 夜叉丸さん
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85122  Re[4]: 正規表現の考え方がわかりません
□投稿者/ 夜叉丸 -(2017/09/12(Tue) 10:20:13)
    No85030 (WebSurfer さん) に返信

    >
    > プロパティとして X, Y, Width, Height が提供されているのですから、それを使えばいいのですから。
    >
    > このような質問をしたのはどういう理由でしょう。教えていただけませんか? > 夜叉丸さん

    Rectangle や Size を ToString() で出力されたテキスト(CSV)ファイルがあります。
    このデータを自分で作ったプログラムの取り込みたいだけなのですが、
    width とか , とか = で Index を使ってやろうとしていたのですが、調べていると Match というのがあるとわかって
    利用しようと思ったのですが、正規表現が理解できなくて取得がうまくできなかったのです。

    string 等のプロパティで X, Y, Width, Height があるのでしょうか?
    それとも、ParseExact のような形で取得できるのでしょうか?


記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85123  Re[5]: 正規表現の考え方がわかりません
□投稿者/ Hongliang -(2017/09/12(Tue) 10:38:53)
    > string 等のプロパティで X, Y, Width, Height があるのでしょうか?
    > それとも、ParseExact のような形で取得できるのでしょうか?

    出力するときに単に
    writer.WriteLine("{0},{1}", id, rect);
    みたいに書き込むのではなく、
    writer.WriteLine("{0},{1},{2},{3},{4}", id, rect.X, rect.Y, rect.Width, rect.Height);
    みたいに出力しておけば、いちいち解析しなくて済んだって話ですね。
    すでに前者のようなデータが存在する状況では今更な話ではあります。
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85124  Re[6]: 正規表現の考え方がわかりません
□投稿者/ 夜叉丸 -(2017/09/12(Tue) 10:48:04)
    No85123 (Hongliang さん) に返信

    > すでに前者のようなデータが存在する状況では今更な話ではあります。

    おっしゃる通りです。
    でも、私もやってしまうかもしれませんね。ToString って簡単に文字列にしてくれるし
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85130  Re[5]: 正規表現の考え方がわかりません
□投稿者/ WebSurfer -(2017/09/12(Tue) 12:11:35)
    No85122 (夜叉丸 さん) に返信

    Hongliang さんのレスとダブるところがありますが・・・

    > Rectangle や Size を ToString() で出力されたテキスト(CSV)ファイルがあります。

    既存の「テキスト(CSV)ファイル」があって、それを作るのは質問者さんの責任範囲外、
    かつ、作る人にこのように作ってくれと注文を出せる立場にもないのであれば、今回の話
    のように正規表現を使って抜き出すというのはやむを得ないと思います。

    そうではなくて、質問者さんが「テキスト(CSV)ファイル」の作成方法が指定できるので
    あれば、正規表現など使わなくても取得できるように、最初から「テキスト(CSV)ファイル」
    の形式を考えておくべきと思います。
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85010  Re[1]: 正規表現の考え方がわかりません
□投稿者/ 魔界の仮面弁士 -(2017/09/05(Tue) 10:57:21)
    2017/09/05(Tue) 11:36:37 編集(投稿者)

    No85005 (夜叉丸 さん) に返信
    > ra.ToString() = "{X=3, Y=6, Width=9, Height=12}"
    > Match m = new Regex(@"{X=(?<X>[-]*\d+),Y=(?<Y>[-]*\d+),Width=(?<Width>[-]*\d+),Height=(?<Height>[-]*\d+)}").Match(ra.ToString());

    これではヒットしないと思いますよ。元の文字列が
    "{X=3, Y=6, Width=9, Height=12}" ではなく
    "{X=3,Y=6,Width=9,Height=12}" であったのなら、
    m.Groups["X"] で拾えるでしょうけれども。

    カンマの後に空白を許容したいのであれば、
    "," ではなく ", " や ",\s*" に変更してみてください。


    > int ix = (int.TryParse(m.Groups["X"].ToString(), out ix)) ? ix : 0;
    false 判定時には 0 が出力される仕様なので、三項演算子を使わずに
     int ix; int.TryParse(m.Groups["X"].ToString(), out ix);
    あるいは
     int ix; int.TryParse(m.Groups["X"].Value, out ix);
    でも OK ですね。


    > この場合
    > "3" = "(?<X>[-]*\d+)" であらわされるということですよね。
    元の文字列に空白が含まれていなければ "3" になると思います。


    > [-] 連続した文字範囲の1文字 : あるかもしれないしないかもしれないマイナスフラグ
    "[-]" は "-" と同義で、それ自体は単なる - 記号です。


    > * 直前の文字が0回以上繰り返す。 : なので先頭だから繰り返さないので0回以上?
    すなわち、"X=---3" のような文字列に対してもヒットします。
    この場合、--- 部がキャプチャされて m.Groups["X"].Value == "---3" となります。

    もしも「符号があるかもしれないし無いかもしれない」にしたいのであれば、
    "[+-]?" の方が良いかもしれません。


    > \d 0から9までの数字       : 数字を使用
    半角の "3" だけでなく
    全角の "3" にもヒットします。


    > ところが同様にfloat の場合どうすればよいのかわかりません。
    単純には
     [+-]?[0-9]+[.]?[0-9]([eE][+-])?[0-9]
    などが思い当たります。

    float 値として float.NaN や float.NegativeInfinity が含まれる場合にも
    対処が必要なら、もう一ひねり必要かも知れません。


    // RectangleF r = new RectangleF(float.Epsilon, float.NaN, float.NegativeInfinity, float.PositiveInfinity);
    // string rs = r.ToString();
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

■85015  Re[2]: 正規表現の考え方がわかりません
□投稿者/ 夜叉丸 -(2017/09/05(Tue) 13:55:07)
    No85010 (魔界の仮面弁士 さん) に返信
    > 2017/09/05(Tue) 11:36:37 編集(投稿者)

    >>ra.ToString() = "{X=3, Y=6, Width=9, Height=12}"
    >>Match m = new Regex(@"{X=(?<X>[-]*\d+),Y=(?<Y>[-]*\d+),Width=(?<Width>[-]*\d+),Height=(?<Height>[-]*\d+)}").Match(ra.ToString());
    >
    > これではヒットしないと思いますよ。元の文字列が
    > "{X=3, Y=6, Width=9, Height=12}" ではなく
    > "{X=3,Y=6,Width=9,Height=12}" であったのなら、
    > m.Groups["X"] で拾えるでしょうけれども。

    Rectangle ra = new Rectangle(3,6,9,12);
    です。確認したら"{X=3,Y=6,Width=9,Height=12}"でした。

    > 単純には
    >  [+-]?[0-9]+[.]?[0-9]([eE][+-])?[0-9]
    > などが思い当たります。
    例外はハンドルされていませんとなります。
    System.ArgumentException:'解析中 "{X~(?<X>[+-]?[0-9]+.]?[0-9]([eE]・・・・・

    RectangleF raf = new RectangleF(3f, -6.2f, 9.3f, 12.4f);
    Match f = new Regex(@"{X=(?<X>[+-]?[0-9]+[.]?[0-9]([eE][+-])?[0-9])," +
    "Y=(?<Y>[+-]?[0-9]+[.]?[0-9]([eE][+-])?[0-9])," +
    "Width=(?<Width>[+-]?[0-9]+[.]?[0-9]([eE][+-])?[0-9]))," +
    "Height=(?<Height>[+-]?[0-9]+[.]?[0-9]([eE][+-])?[0-9]))}").Match(raf.ToString());
記事No.85005 のレス /過去ログ145より / 関連記事表示
削除チェック/

次の20件>

<< 0 | 1 >>

パスワード/

- Child Tree -