基本的にこれであるという要件があります。次のようなテキストの文字列がある場合
"There once was an 'ugly' duckling but it could
never have been \'Scarlett\' Johansen"
次に、まだエスケープされていない引用符を一致させたいと思います。これらは、「スカーレット」の周りのものではなく、「醜い」の周りのものになります。
私はこれにかなりの時間を費やして、小さなC#コンソールアプリを使用してテストを行い、次の解決策を考え出しました。
private static void RegexFunAndGames() {
string result;
string sampleText = @"Mr. Grant and Ms. Kelly starred in the film \'To Catch A Thief' but not in 'Stardust' because they'd stopped acting by then";
string rePattern = @"\\'";
string replaceWith = "'";
Console.WriteLine(sampleText);
Regex regEx = new Regex(rePattern);
result = regEx.Replace(sampleText, replaceWith);
result = result.Replace("'", @"\'");
Console.WriteLine(result);
}
基本的に、私が行ったことは、すでにエスケープされている文字を見つける2つのステップのプロセスであり、それを元に戻してから、すべてをやり直します。少し不器用に聞こえますが、もっと良い方法があるのではないかと思います。
テスト情報
私は2つの本当に良い答えを得たので、どちらがより良いかを確認するためにテストを実行する価値があると思いました。私には次の2つの機能があります。
private static string RegexReplace(string sampleText) {
Regex regEx = new Regex("(?<!\\\\)'");
return regEx.Replace(sampleText, "\\'");
}
private static string ReplaceTest(string sampleText) {
return sampleText.Replace(@"\'", "'").Replace("'", @"\'");
}
そして、コンソールアプリのMainメソッドを介してそれらを呼び出します。
static void Main(string[] args) {
string sampleText = @"Mr. Grant and Ms. Kelly starred in the film \'To Catch A Thief' but not in 'Stardust' because they'd stopped acting by then.";
string testReplace = string.Empty;
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (int i = 1000000; i > 0; i--) {
testReplace = ReplaceTest(sampleText);
}
sw.Stop();
Console.WriteLine("This method took '" + sw.ElapsedMilliseconds.ToString() + "'");
sw.Reset();
sw.Start();
for (int i = 1000000; i > 0; i--) {
testReplace = RegexReplace(sampleText);
}
sw.Stop();
Console.WriteLine("This method took '" + sw.ElapsedMilliseconds.ToString() + "'");
}
メソッドReplaceTestは2068ミリ秒かかります。RegexReplaceメソッドは9372ミリ秒かかります。私はこのテストを数回実行しましたが、ReplaceTestは常に最速で実行されます。