tags:

views:

92

answers:

5

NOTE: This is not a simple string replace question.

SomethingBlahBlah can be #SomeThingOtherthanThis

My case is as follows, I have a large string (<1024B, but >300B), that will have {#String} and {$String}.

To be more specific {#SomethingBlahBlah} and {$SomeOtherThingBlahBlah}, so in regexp {#w+} and {$w+}

My first question is, are regexps the only way to do it? I'd love a string replace solution or such, and secondly if it is, is there a way to just do one compiled regex and do a single pass through?

Can Linq help by any chance?

A: 
String.Replace("SomethingBlahBlah", "SomeOtherThingBlahBlah")

Edit: Just found a great answer by Jon Skeet in this thread.

kzen
This would be a two-pass algorithm: once for replacing `{#Text}` and another for replacing `{$Text}`. The OP explicitly requested a one-pass solution.
Kirk Woll
I don't think "is there a way to just do one compiled regex and do a single pass through?" qualifies as an explicit request for a one-pass solution...
kzen
A: 

Regex takes more time to replace text instead of using String.Replace method. But Regex give you a huge power with text manipulation. LINQ hasn't a direct methods to work with string. It only can use existing features.

Yuriy
+2  A: 

For a large string, and several different replacements, I would recommend using StringBuilder.

StringBuilder sb = new StringBuilder(input);
sb.Replace("{$String}", "Real Value");
sb.Replace("{$SomeOtherThingBlahBlah}", "Another Real Value");
return sb.ToString();

Manipulations will happen in memory, and a new string will not be allocated until you call ToString().

Matt Brunell
That's exactly what JS suggested in a thread I just added to my answer...
kzen
+1  A: 

You can use one of these:

Option 1

Regex:

\{(?:#|\$)(\w+)}

Text:

{#SomethingBlahBlah} and {$SomeOtherThingBlahBlah}

Returns:

Result 1

   1. SomethingBlahBlah

Result 2

   1. SomeOtherThingBlahBlah

Option 2

Regex:

(\{(?:#|\$)(?:\w+)})

Text:

{#SomethingBlahBlah} and {$SomeOtherThingBlahBlah}

Returns:

Result 1

   1. {#SomethingBlahBlah}

Result 2

   1. {$SomeOtherThingBlahBlah}
tinifni
thanks this is what is was looking for
No problem. You might want to investigate Matt Brunell's answer though. Don't forget to accept an answer once you have found one that suits you. Happy coding!
tinifni
+1  A: 

IndexOf vs Regex: Tested using Stopwatch ticks over 100000 iterations with 500~ length string.

Method IndexOf

public static string Re(string str)
{
    int strSIndex = -1;
    int strEIndex = -1;

    strSIndex = str.IndexOf("{#");
    if (strSIndex == -1) strSIndex = str.IndexOf("{$");
    if (strSIndex == -1) return str;

    strEIndex = str.IndexOf("}");
    if (strEIndex == -1) return str;

    if (strEIndex < strSIndex)
    {
        strSIndex = str.IndexOf("{$");
        if (strSIndex == -1) return str;
    }

    str = str.Substring(0, strSIndex) + str.Substring(strEIndex + 1);

    return Re(str);
}

Regex Method

Regex re = new Regex(@"\{(?:#|\$)(\w+)}", RegexOptions.Compiled);
re.Replace(str, "");

Results (few replaces):

Fn: IndexOf
Ticks: 1181967

Fn: Regex
Ticks: 1482261

Notice that regex was set to compile before the iterations.

Results (lots of replaces):

Fn: Regex
Ticks: 19136772

Fn: IndexOf
Ticks: 37457111
BrunoLM
Regex from @tinifni's answer.
BrunoLM
Thanks! This is *EXACTLY* what I wanted :-)