简体   繁体   中英

RegEx.Replace is only replacing first occurrence, need all

I'm having an issue with Regex.Replace in C# as it doesn't seem to be replacing all occurrences of the matched pattern.

private string ReplaceBBCode(string inStr)  
{  
    var outStr = Regex.Replace(inStr, @"\[(b|i|u)\](.*?)\[/\1\]", @"<$1>$2</$1>", RegexOptions.IgnoreCase | RegexOptions.Multiline);  
    outStr = Regex.Replace(outStr, "(\r|\n)+", "<br />"); 
    return outStr; 
}

The input string:

[b]Saint Paul's Food Kitchen[/b]    [b]  [/b]Saint Paul's food kitchen opens weekly to provide food to those in need.

The result:

<b>Saint Paul's Food Kitchen</b>    [b]  [/b]Saint Paul's food kitchen opens weekly to provide food to those in need.

I've tested this in regexhero.net and it works exactly as it should there.

EDIT:
Sorry, copied the wrong version of the function. It now shows the correct code, that behaves incorrectly for me.

The output I'm getting is completely different from what you say you're getting, but

The biggest problem I see, is that you probably don't want your regex to be greedy.

try replacing the .* with .*?

No need for Regex:

private static string ReplaceBBCode(string inStr)  
{  
    return inStr.Replace("[b]", "<b>").Replace("[/b]", "</b>")
                .Replace("[i]", "<i>").Replace("[/i]", "</i>")
                .Replace("[u]", "<u>").Replace("[/u]", "</u>")
                .Replace("\r\n", "\n")
                .Replace("\n", "<br />"); 
}

I like this one better:

private static string ReplaceBBCode(string inStr)  
{
    StringBuilder outStr = new StringBuilder();
    bool addBR = false;
    for(int i=0; i<inStr.Length; i++){
        if (addBR){
            outStr.Append("<br />");
            addBR = false;
        }
        if (inStr[i] == '\r' || inStr[i] == '\n'){
            if (!addBR)
                addBR = true;
        }
        else {
            addBR = false;
            if (i+2 < inStr.Length && inStr[i] == '[' 
                && (inStr[i+1] == 'b' ||  inStr[i+1] == 'i' ||  inStr[i+1] == 'u')
                && inStr[i+2] == ']'){
                outStr.Append("<").Append(inStr[i+1]).Append(">");
                i+=2;
            }
            else if(i+3 < inStr.Length && inStr[i] == '[' && inStr[i+1] == '/'
                && (inStr[i+2] == 'b' ||  inStr[i+2] == 'i' ||  inStr[i+2] == 'u')
                && inStr[i+3] == ']'){
                outStr.Append("</").Append(inStr[i+2]).Append(">");
                i+=3;
            }
            else
                outStr.Append(inStr[i]);
        }
    }
    return outStr.ToString();
}

This solved the issue, it also handles nested tags. Not sure why, but rebuilding over and over it still was causing errors. Its possible our VS2010 is corrupted and not building properly, or that the framework is corrupted. Not sure what the cause of the problem is, but this solved it:

private string ReplaceBBCode(string inStr)
{
    var outStr = inStr;
    var bbre = new Regex(@"\[(b|i|u)\](.*?)\[/\1\]", RegexOptions.IgnoreCase | RegexOptions.Multiline);
    while( bbre.IsMatch(outStr))
        outStr = bbre.Replace(outStr, @"<$1>$2</$1>");
    outStr = Regex.Replace(outStr, "(\r|\n)+", "<br />");
    return outStr;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM