简体   繁体   中英

Regex - capturing repeated groups in C#

I have a tough time writing a C regular expression. I want to write an expression which can catch abc . For example, I have a string:

<a href="function(##abc##);function(##abc##)">

I want to capture abc and replace it with xyz .

I have tried something like (")([^"]*)(##abc##)([^"]*)(")

This captures the first occurrence of abc but not the second one. Can someone help?

Thanks

In some programming-languages you have to set a global-Flag to achieve that all occurences are matched, not only the first one. Often the Flag is a „g“

You can use a match evaluator as such:

private class Replacer
{
    private bool inQuotes;
    public string Replace( Match m ){
        if( m.Value == "\"" ){
            inQuotes = ! inQuotes;
        }else if ( inQuotes && m.Value == "##abc##" ){
            return "##xyz##";
        }
        return m.Value;
    }
}

input = "<a href=\"function(##abc##);function(##abc##)\">";
Console.WriteLine( Regex.Replace( input, "\"|(##abc##)", (new Replacer()).Replace ) );

Which outputs:

<a href="function(##xyz##);function(##xyz##)">

Although if you're working with XML you probably want to use XPath to first find the text between the quotes, and then use a regex or direct string replace to do the replacement. If you're working with HTML (which isn't XHTML) you can use a library like http://htmlagilitypack.codeplex.com/ to do something similar.

Alternatively (and probably the worst option) to use a single regex this seems to do the job but isn't pretty:

Match match = (new Regex("(?:\")([^\"]*?(##abc##))+[^\"]*(?:\")")).Match(input);

You can then iterate over each of the matches in match.Groups[2].Captures. Though you would have to do the actual replacement manually based using the index and length of each capture.

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