質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

Q&A

解決済

1回答

8524閲覧

C# 正規表現(Regex)とLINQを使用して結果が想定通り取得できない

monchiken

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

0グッド

0クリップ

投稿2016/01/16 03:56

foreachを使用したコードをLINQを使用するコードにしたいのですが、書き方が分かりません。
どのように記述すれば同等の事が出来るのでしょうか。

実現したい処理は、
文字列配列から郵便番号と住所の文字列が含まれる文字列を探しだしてDataクラスに設定する処理です。

c#

1Regex regex = new Regex(@"(〒\d{3}-\d{4})\t*([^\t]*)"); 2Data data = new Data(); 3 4//住所が記載されている行は1行もしくは0行 5string[] values = new string[] { "AA", " 〒111-1111 ◯◯県△△町 ", "BB" };

foreachを利用すると以下のようにして、実現できました。

c#

1foreach(string text in values ) 2{ 3 if(regex.IsMatch(text)) 4 { 5 data.PostCode = regex.Match(text).Groups[1].Value; //"〒111-1111" 6 data.Address = regex.Match(text).Groups[2].Value; //"◯◯県△△町" 7 } 8}

LINQを使って以下のコードだと
resultはnullではないですが、何も取得できていないらしく「IndexOutOfRangeException」が発生します。

c#

1var result = 2 values 3 .Where(v => regex.IsMatch(v)) 4 .Select(v => regex.Match(v).Groups) 5 .Where(g => g.Count != 0) 6 .Select(s => new { Postcode = s[1].Value, Address = s[2].Value }); 7 8if (result != null) 9{ 10 data.Postcode = result.ToArray()[0].Postcode; 11 data.Address = result.ToArray()[0].Address; 12}

let句を使用したのが以下のコードなのですが、
上記と同様に何も取得できていないらしく「IndexOutOfRangeException」が発生します。

c#

1var result = 2 from value in values 3 where regex.IsMatch(value ) 4 let g = regex.Match(value ).Groups 5 where g.Count != 0 6 select new { Postcode = g[1].Value, Address = g[2].Value }; 7 8if (result != null) 9{ 10 data.Postcode = result.ToArray()[0].Postcode; 11 data.Address = result.ToArray()[0].Address; 12}

以上、アドバイスよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ちょっとやってみましたが、IndexOutOfRangeExceptionは発生しません。
住所データが間違っていませんか、下記の住所データを★に変更し、住所なしにしたときに、IndexOutOfRangeExceptionが発生します。
以下がコードです。

C#

1static void Main(string[] args) 2{ 3 Regex regex = new Regex(@"(〒\d{3}-\d{4})\t*([^\t]*)"); 4 Data data = new Data(); 5 6 //住所が記載されている行は1行もしくは0行 7 string[] values = new string[] { "AA", " 〒111-1111 ◯◯県△△町 ", "BB" }; 8 //string[] values = new string[] { "AA", "BB" }; // ★住所なしデータ 9 var result = values.Where(v => regex.IsMatch(v)) 10 .Select(v => regex.Match(v).Groups) 11 .Where(g => g.Count != 0) 12 .Select(s => new { Postcode = s[1].Value, Address = s[2].Value }); 13 14 if (result != null) 15 { 16 data.PostCode = result.ToArray()[0].Postcode; 17 data.Address = result.ToArray()[0].Address; 18 } 19}

住所が見つからないときでも、resultはnullにならないようです。Count()でチェックした方が良いと思います。

C#

1if (result.Count() != 0) // チェックの変更 2{ 3 data.PostCode = result.ToArray()[0].Postcode; 4 data.Address = result.ToArray()[0].Address; 5}

投稿2016/01/16 07:46

akiruno-oneone

総合スコア815

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

monchiken

2016/01/16 14:20

検証などもしていただき、誠にありがとうございます。 まさに仰るとおりでした。 実際のコードでString配列はXMLファイルから取得するようにしてます。 string[] getDataFromXmlFile(string tagName) foreach版とLINQ版で指定するタグ名が異なっていた(スペルミス)していたため、そもそも取得ができていない状態でした。 また、こちらでもLINQで取得した結果は0件でもnullにはなっておりませんでした。 チェックする箇所もCountで判断した所、例外は発生することが無くなりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問