केवल कुछ समूहों को Regex से बदलें


190

मान लीजिए कि मेरे पास निम्नलिखित रेगेक्स है:

-(\d+)-

और मैं बदलने के लिए, सी #, समूह 1 का उपयोग कर चाहते हैं (\d+)के साथ AAप्राप्त करने के लिए,:

-AA-

अब मैं इसका उपयोग करके प्रतिस्थापित कर रहा हूं:

var text = "example-123-example";
var pattern = @"-(\d+)-";
var replaced = Regex.Replace(text, pattern, "-AA-"); 

लेकिन मुझे वास्तव में यह पसंद नहीं है, क्योंकि अगर मैं बदले के पैटर्न को बदलूं, तो मुझे _(\d+)_प्रतिस्थापन स्ट्रिंग को _AA_भी बदलना होगा , और यह DRY सिद्धांत के खिलाफ है।

मैं कुछ इस तरह की तलाश में हूँ:

मिलान किए गए पाठ को ठीक से कैसे रखें, लेकिन समूह 1 को this textसमूह 2 से बदलकर रखें another text...

संपादित करें:
यह सिर्फ एक उदाहरण था। मैं बस वही कर रहा हूँ जो मैंने ऊपर कहा था।

इसके लिए काम करना चाहिए:

anything(\d+)more_text और किसी भी पैटर्न की आप कल्पना कर सकते हैं।

मैं केवल यही करना चाहता हूं कि केवल समूहों को बदल दिया जाए, और शेष मैच को बनाए रखा जाए।

जवाबों:


307

एक अच्छा विचार समूहों के अंदर हर चीज को घेरना हो सकता है, भले ही उन्हें पहचानने की आवश्यकता हो या नहीं। इस तरह से आप उन्हें अपने प्रतिस्थापन स्ट्रिंग में उपयोग कर सकते हैं। उदाहरण के लिए:

var pattern = @"(-)(\d+)(-)";
var replaced = Regex.Replace(text, pattern, "$1AA$3"); 

या माचिस की तीली का उपयोग करना:

var replaced = Regex.Replace(text, pattern, m => m.Groups[1].Value + "AA" + m.Groups[3].Value);

एक और तरीका, थोड़ा गन्दा, एक तलाश / लुकहेड का उपयोग किया जा सकता है:

(?<=-)(\d+)(?=-)


17
मैंने अधिक जानकारी प्रदान करने के लिए आपके उत्तर को संपादित किया, लेकिन आपने जो कहा वह पूरी तरह से सही है। पता नहीं कैसे मैं चूक गया कि मैं समूहों के अंदर सब कुछ डाल सकता हूं, कोई फर्क नहीं पड़ता कि उनका उपयोग करेगा या नहीं :) । मेरी राय में, यह समाधान लुकहेड और लुकबाइंड का उपयोग करने की तुलना में बहुत बेहतर और क्लीनर है।
ऑस्कर मेडेरोस

छोटा टाइपो, आपका प्रतिस्थापन पैटर्न $ 1AA $ 3
मिस्टर जूल

1
काम करने के लिए इस के लिए आदेश में, मैं जोड़ने के लिए किया था .Valueके लिए m.Groups[1]आदि
jbeldock

11
यह भी ध्यान देने योग्य है - यदि आपका प्रतिस्थापन पाठ एक संख्या से शुरू होता है, तो पहला समाधान ("$ 1AA $ 3") उद्देश्य के अनुसार काम नहीं करेगा!
बर्टी

2
@OscarMederos आप गैर कैप्चरिंग समूहों का उपयोग कर सकते हैं - उन समूहों के लिए अच्छा है जिनका आप उपयोग नहीं करते हैं। में (?:foo)(bar), $1की जगह लेगा barअधिक विवरण
पैट्रिक


19

मुझे इसकी आवश्यकता भी थी और मैंने इसके लिए निम्नलिखित विस्तार विधि बनाई:

public static class RegexExtensions
{
    public static string ReplaceGroup(
        this Regex regex, string input, string groupName, string replacement)
    {
        return regex.Replace(
            input,
            m =>
            {
                var group = m.Groups[groupName];
                var sb = new StringBuilder();
                var previousCaptureEnd = 0;
                foreach (var capture in group.Captures.Cast<Capture>())
                {
                    var currentCaptureEnd =
                        capture.Index + capture.Length - m.Index;
                    var currentCaptureLength =
                        capture.Index - m.Index - previousCaptureEnd;
                    sb.Append(
                        m.Value.Substring(
                            previousCaptureEnd, currentCaptureLength));
                    sb.Append(replacement);
                    previousCaptureEnd = currentCaptureEnd;
                }
                sb.Append(m.Value.Substring(previousCaptureEnd));

                return sb.ToString();
            });
    }
}

उपयोग:

var input = @"[assembly: AssemblyFileVersion(""2.0.3.0"")][assembly: AssemblyFileVersion(""2.0.3.0"")]";
var regex = new Regex(@"AssemblyFileVersion\(""(?<version>(\d+\.?){4})""\)");


var result = regex.ReplaceGroup(input , "version", "1.2.3");

परिणाम:

[assembly: AssemblyFileVersion("1.2.3")][assembly: AssemblyFileVersion("1.2.3")]

मुझे यह कार्यान्वयन पसंद है लेकिन यह कई मैचों की जगह नहीं लेता है। मैंने एक संस्करण पोस्ट किया है
व्लादिमीर

13

यदि आप अपना पैटर्न नहीं बदलना चाहते हैं तो आप मिलान किए गए समूह के समूह सूचकांक और लंबाई गुणों का उपयोग कर सकते हैं।

var text = "example-123-example";
var pattern = @"-(\d+)-";
var regex = new RegEx(pattern);
var match = regex.Match(text);

var firstPart = text.Substring(0,match.Groups[1].Index);    
var secondPart = text.Substring(match.Groups[1].Index + match.Groups[1].Length);
var fullReplace = firstPart + "AA" + secondPart;

कृपया ध्यान दें कि यह मानता है और केवल मैच की पहली घटना के लिए काम करेगा।
बार्टोज़

5

यहां एक और अच्छा स्वच्छ विकल्प है जिसे आपके पैटर्न को बदलने की आवश्यकता नहीं है।

        var text = "example-123-example";
        var pattern = @"-(\d+)-";

        var replaced = Regex.Replace(text, pattern, (_match) =>
        {
            Group group = _match.Groups[1];
            string replace = "AA";
            return String.Format("{0}{1}{2}", _match.Value.Substring(0, group.Index - _match.Index), replace, _match.Value.Substring(group.Index - _match.Index + group.Length));
        });

0

अलग समूह प्रतिस्थापन प्राप्त करने के लिए नीचे दिए गए कोडिंग के माध्यम से जाएं।

new_bib = Regex.Replace(new_bib, @"(?s)(\\bibitem\[[^\]]+\]\{" + pat4 + @"\})[\s\n\v]*([\\\{\}a-zA-Z\.\s\,\;\\\#\\\$\\\%\\\&\*\@\\\!\\\^+\-\\\=\\\~\\\:\\\" + dblqt + @"\\\;\\\`\\\']{20,70})", delegate(Match mts)
                    {
                           var fg = mts.Groups[0].Value.ToString(); 
                           var fs = mts.Groups[1].Value.ToString();
                           var fss = mts.Groups[2].Value.ToString();
                               fss = Regex.Replace(fss, @"[\\\{\}\\\#\\\$\\\%\\\&\*\@\\\!\\\^+\-\\\=\\\~\\\:\\\" + dblqt + @"\\\;\\\`\\\']+", "");
                           return "<augroup>" + fss + "</augroup>" + fs;
                    }, RegexOptions.IgnoreCase);

0

यहां डैनियल के समान एक संस्करण है लेकिन कई मैचों की जगह:

public static string ReplaceGroup(string input, string pattern, RegexOptions options, string groupName, string replacement)
{
    Match match;
    while ((match = Regex.Match(input, pattern, options)).Success)
    {
        var group = match.Groups[groupName];

        var sb = new StringBuilder();

        // Anything before the match
        if (match.Index > 0)
            sb.Append(input.Substring(0, match.Index));

        // The match itself
        var startIndex = group.Index - match.Index;
        var length = group.Length;
        var original = match.Value;
        var prior = original.Substring(0, startIndex);
        var trailing = original.Substring(startIndex + length);
        sb.Append(prior);
        sb.Append(replacement);
        sb.Append(trailing);

        // Anything after the match
        if (match.Index + match.Length < input.Length)
            sb.Append(input.Substring(match.Index + match.Length));

        input = sb.ToString();
    }

    return input;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.