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

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

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

Re[4]: C#の正規表現について


(過去ログ 121 を表示中)

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

■72366 / inTopicNo.1)  C#の正規表現について
  
□投稿者/ あ (1回)-(2014/06/05(Thu) 17:00:37)

分類:[C#] 

2014/06/05(Thu) 17:18:25 編集(投稿者)
2014/06/05(Thu) 17:15:24 編集(投稿者)

VisualStudio2010でC#を使用しています。


正規表現を使用しての特定の値の削除をしようと思っています。

#Region "No.■■■
・・
・・
#End Region

No.■■■の特定の番号の場合に削除をしたいです。
■■■は複数あります。
・・の部分は半角の文が入っています。

正規表現は
"#Region \"No." + ban[i] + "\r\n"+"*.*?#End Region"
このように書きました。
しかし
"*.*?#End Region"←この部分がうまくいっていないため、削除されません。
どのように書けば表示されるのか、どなたかご教授お願いいたします。

以下、ソースを貼り付けます。
特定の値は参照ボタンを作成し、自分でデータを持ってきて削除をさせています。
データの取得はできています。

System.IO.StreamReader sr = new System.IO.StreamReader(textBox2.Text,
System.Text.Encoding.GetEncoding("UTF-8"));
//内容をすべて読み込む
string s = sr.ReadToEnd();

int[] ban = { 99,100 };

for (int i = 0; i < ban.Length; i++)
{

String patternStr = "#Region \"No." + ban[i] +"*?#End Region";
s = Regex.Replace(s, patternStr, string.Empty);
Console.WriteLine(s);

}

Encoding sjisEnc = Encoding.GetEncoding("UTF-8");
StreamWriter writer =new StreamWriter(@"C:\Test.txt", true, sjisEnc);
writer.WriteLine(s);

//閉じる
sr.Close();
writer.Close();

MessageBox.Show("作成されました");
}

catch
{
MessageBox.Show("参照できません");
}

以上、拙い文書ですがどなたかよろしくお願いいたします。
引用返信 編集キー/
■72375 / inTopicNo.2)  Re[1]: C#の正規表現について
□投稿者/ Azulean (316回)-(2014/06/05(Thu) 23:08:28)
通常の Regex では1行の中でマッチするかどうか判定するので、複数行をまたがってマッチさせるには RegexOptions.Multiline を指定しなければなりません。
また、このやり方の場合、#Region/#End Region の入れ子に対応できないのではないかと予想されますが、そういった入力はないと考えて差し支えないでしょうか。
引用返信 編集キー/
■72376 / inTopicNo.3)  Re[1]: C#の正規表現について
□投稿者/ 渋木宏明 (18回)-(2014/06/05(Thu) 23:12:33)
渋木宏明 さんの Web サイト
> "*.*?#End Region"←この部分がうまくいっていないため、削除されません。
> どのように書けば表示されるのか、どなたかご教授お願いいたします。

正規表現は最長一致するのが仕様です。

なので、単一の正規表現で意図したマッチを得るのは無理だと思います。

やるとしたら、正規表現で region の開始位置を列挙して、それぞれの region 開始位置から直近の end region を探す、とかでしょう。

引用返信 編集キー/
■72377 / inTopicNo.4)  Re[2]: C#の正規表現について
□投稿者/ 渋木宏明 (19回)-(2014/06/05(Thu) 23:15:08)
渋木宏明 さんの Web サイト
> また、このやり方の場合、#Region/#End Region の入れ子に対応できないのではないかと予想されますが、そういった入力はないと考えて差し支えないでしょうか。

確かに、入れ子の対応まで考えるとちょっとメンドクサイですね。

# Roslyn 使ってみるのも面白いかな?
引用返信 編集キー/
■72383 / inTopicNo.5)  Re[1]: C#の正規表現について
□投稿者/ shu (581回)-(2014/06/06(Fri) 09:09:52)
No72366 (あ さん) に返信

サンプルです。
VB.NETですが適当に変換してみて下さい。

        Dim reg As New Regex("#Region ""No\.(?<No>\d+)""(\r|\n|.)*?#End Region(\r|\n){0,2}", RegexOptions.Multiline)
        Dim Src As New StringBuilder

        Src.Length = 0
        Src.AppendLine("aaaa")
        Src.AppendLine("bbbb")
        Src.AppendLine()
        Src.AppendLine("#Region ""No.99""")
        Src.AppendLine("No.99_1")
        Src.AppendLine("No.99_2")
        Src.AppendLine("No.99_3")
        Src.AppendLine("#End Region")
        Src.AppendLine()
        Src.AppendLine("#Region ""No.95""")
        Src.AppendLine("No.95_1")
        Src.AppendLine("No.95_2")
        Src.AppendLine("No.95_3")
        Src.AppendLine("#End Region")
        Src.AppendLine()
        Src.AppendLine("cccc")
        Src.AppendLine("dddd")
        Src.AppendLine()
        Src.AppendLine("#Region ""No.100""")
        Src.AppendLine("No.100_1")
        Src.AppendLine("No.100_2")
        Src.AppendLine("No.100_3")
        Src.AppendLine("#End Region")
        Src.AppendLine()
        Src.AppendLine("#Region ""No.101""")
        Src.AppendLine("No.101_1")
        Src.AppendLine("No.101_2")
        Src.AppendLine("No.101_3")
        Src.AppendLine("#End Region")
        TextBox1.Text = Src.ToString

        Dim des = reg.Replace(Src.ToString, Function(m)
                                                Dim No = CInt(m.Groups("No").Value)
                                                Select Case No
                                                    Case 99, 100
                                                        Return String.Empty
                                                    Case Else
                                                        Return m.Value
                                                End Select
                                            End Function)
        TextBox2.Text = des

引用返信 編集キー/
■72387 / inTopicNo.6)  Re[2]: C#の正規表現について
□投稿者/ あ (2回)-(2014/06/06(Fri) 10:09:21)
Azulean様
渋木宏明様
shu様

皆様ご返信ありがとうございます。
なんとか自分で解決することができました。
改行をなくすことで削除ができるようです。

以下、ソースを貼り付けます。

System.IO.StreamReader sr = new System.IO.StreamReader(textBox2.Text,
System.Text.Encoding.GetEncoding("UTF-8"));
//内容をすべて読み込む
string s = sr.ReadToEnd();

int[] ban = { 99,101 };


//改行変更
s = s.Replace("\r\n", "");
for (int i = 0; i < ban.Length; i++)
{

String patternStr = "#Region \"No." + ban[i] +".*?#End Region";
s = Regex.Replace(s, patternStr, string.Empty);
Console.WriteLine(s);

}

Encoding sjisEnc = Encoding.GetEncoding("UTF-8");
StreamWriter writer =new StreamWriter(@"C:\Test.txt", true, sjisEnc);
writer.WriteLine(s);

//閉じる
sr.Close();
writer.Close();

なお、この問題点としては改行をなくしたため、文章が非常に読みづらいことと、元の文の形を保持しての削除ができないことです。
この問題点についてはまだ解決しておりません。
どなたかご教授お願いいたします。
引用返信 編集キー/
■72388 / inTopicNo.7)  Re[3]: C#の正規表現について
□投稿者/ shu (582回)-(2014/06/06(Fri) 10:18:31)
No72387 (あ さん) に返信
> なお、この問題点としては改行をなくしたため、文章が非常に読みづらいことと、元の文の形を保持しての削除ができないことです。
> この問題点についてはまだ解決しておりません。
> どなたかご教授お願いいたします。
既に提示したサンプルを見てもらうとわかるかと思いますが、
.
には改行が含まれません。
また
No.

.
は\をつけないとどんな文字でも良いことになるので
Not99
とか
Non99
とか
No199
などもまっちしてしまいます。
引用返信 編集キー/
■72459 / inTopicNo.8)  Re[4]: C#の正規表現について
□投稿者/ あ (3回)-(2014/06/10(Tue) 11:40:13)
解決しました。
みなさんありがとうございました。

とりあえずソースを載せます。


      System.IO.StreamReader sr = null;
System.IO.StreamWriter sw = null;
try
{
//選択されたファイルをシフトジスで読み込む
sr = new System.IO.StreamReader(textBox2.Text,
System.Text.Encoding.GetEncoding("shift_jis"));
//内容をすべて読み込む
string s = sr.ReadToEnd();

int[] ban = { 99, 101 };

for (int i = 0; i < ban.Length; i++)
{
//今回の見たいファイルには@は含まれていないので改行を@に
s = s.Replace("\r\n", "@");
String patternStr = "#Region \"No." + ban[i] + ".*?#End Region";
s = Regex.Replace(s, patternStr, string.Empty);
s = s.Replace("@", "\r\n");
Console.WriteLine(s);

}

//Dのフォルダに上書き状態でファイル作成
sw = new System.IO.StreamWriter("D:\\Test.vb", false,
System.Text.Encoding.GetEncoding("shift_jis"));
sw.Write(s);

MessageBox.Show("作成されました");
}

//エラーの場合
catch
{
MessageBox.Show("作成できませんでした");

}
//ファイル閉じる
finally
{
if (sr != null)
{
sr.Close();
}
if (sw != null)
{
sw.Close();
}
}
}
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -