4

基本的にこれであるという要件があります。次のようなテキストの文字列がある場合

"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は常に最速で実行されます。

4

3 に答える 3

4

ネガティブルックビハインドを使用して、引用符がエスケープされていないことを確認できます。以下の式

(?<!\\)'

直前にスラッシュがない限り、一重引用符に一致します。

文字列定数に含まれるスラッシュは2倍にする必要があることに注意してください。

var 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";
var regEx = new Regex("(?<!\\\\)'");
var result = regEx.Replace(sampleText, "\\'");
Console.WriteLine(result);

上記のプリント

Mr. Grant and Ms. Kelly  starred in the film \'To Catch A Thief\' but not in \'Stardust\' because they\'d stopped acting by then

ideoneへのリンク。

于 2012-11-16T16:51:40.710 に答える
3

これを行うために正規表現を使用している理由に驚いています。単純に使用しないのはなぜですか。

string result = sampleText.Replace(@"\'", "'").Replace("'", @"\'");

これにより、エスケープされていないすべてのがエスケープされ'ます。

最初にすべてのエスケープ'(一重引用符)をエスケープ解除し、次にエスケープしallます。

さて、もしそうならRegEx is the requirement、あなたはすでに言ったように正しい解決策を受け入れるつもりです。

于 2012-11-16T18:56:20.447 に答える
-1

あなたが使うことができます

    string rePattern = @"[\\'|\']"; 

その代わり

于 2012-11-16T16:55:21.843 に答える