2010-04-16 18 views
9

के साथ बदलें, मैं स्ट्रिंग के रूप में नियमित अभिव्यक्ति का उपयोग करना चाहता हूं। Format। मैं समझातानाम समूह को रेगेक्स में

मेरे पास है:

string pattern = "^(?<PREFIX>abc_)(?<ID>[0-9])+(?<POSTFIX>_def)$"; 
string input = "abc_123_def"; 
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase); 
string replacement = "456"; 
Console.WriteLine(regex.Replace(input, string.Format("${{PREFIX}}{0}${{POSTFIX}}", replacement))); 

यह काम करता है, लेकिन मैं regex.Replace को "इनपुट" प्रदान करनी चाहिए। मैं नहीं चाहता कि। मैं मिलान के लिए पैटर्न का उपयोग करना चाहता हूं लेकिन स्ट्रिंग प्रारूप के साथ स्ट्रिंग बनाने के लिए भी, नाम के साथ नामित समूह "आईडी" को बदलना चाहता हूं। क्या यह संभव है?

string pattern = "^(?<PREFIX>abc_)(?<ID>[0-9])+(?<POSTFIX>_def)$"; 
string result = ReplaceWithFormat(pattern, "ID", 999); 

परिणाम "abc_999_def" में शामिल होंगे:

मैं की तरह कुछ के लिए देख रहा हूँ। इसे कैसे पूरा करें?

+0

यह वही नहीं है जो आप खोज रहे हैं, लेकिन यह मूल्य हो सकता है। यह मूल रूप से नामित स्ट्रिंग है।अनुक्रमित के बजाय प्रारूप। http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx – chilltemp

उत्तर

12

नहीं, इनपुट प्रदान किए बिना नियमित अभिव्यक्ति का उपयोग करना संभव नहीं है। इसके साथ काम करने के लिए कुछ होना चाहिए, पैटर्न परिणाम में कोई भी डेटा नहीं जोड़ सकता है, सब कुछ इनपुट या प्रतिस्थापन से आना है।

String.Format का उपयोग करने का intead, आप "abc_" और "_def" के बीच हिस्सा निर्दिष्ट करने के लिए आगे पीछे एक नज़र और एक नज़र उपयोग कर सकते हैं, और यह बदल देते हैं:

string result = Regex.Replace(input, @"(?<=abc_)\d+(?=_def)", "999"); 
+9

डाउनवोट क्यों? यदि आप जो भी सोचते हैं वह गलत नहीं है, तो यह उत्तर में सुधार नहीं कर सकता है। – Guffa

+1

उपयोगकर्ता 1817787 –

+0

का उत्तर और टिप्पणी देखें सबसे अच्छा जवाब यह पोस्ट नहीं है लेकिन यह [एक] (http://stackoverflow.com/a/13342795/2183236) है। – fharreau

13

हाँ, यह संभव है :

public static class RegexExtensions 
{ 
    public static string Replace(this string input, Regex regex, string groupName, string replacement) 
    { 
     return regex.Replace(input, m => 
     { 
      return ReplaceNamedGroup(input, groupName, replacement, m); 
     }); 
    } 

    private static string ReplaceNamedGroup(string input, string groupName, string replacement, Match m) 
    { 
     string capture = m.Value; 
     capture = capture.Remove(m.Groups[groupName].Index - m.Index, m.Groups[groupName].Length); 
     capture = capture.Insert(m.Groups[groupName].Index - m.Index, replacement); 
     return capture; 
    } 
} 

उपयोग:

Regex regex = new Regex("^(?<PREFIX>abc_)(?<ID>[0-9]+)(?<POSTFIX>_def)$"); 

string oldValue = "abc_123_def"; 
var result = oldValue.Replace(regex, "ID", "456"); 

परिणाम है: abc_456_def

+2

-1। 'फु गुफा' बेहद अनुचित है। –

+1

अपने jimmies इतनी जंगली मत बनो। – Justin

+0

नहीं, इनपुट प्रदान किए बिना नियमित अभिव्यक्ति का उपयोग करना संभव नहीं है। आप अपने उत्तर में कोड में इनपुट प्रदान कर रहे हैं, इसलिए यह आपके द्वारा दावा किए जाने वाले प्रदर्शन का प्रदर्शन नहीं करता है। – Guffa

3

उपयोगकर्ता 1817787 उत्तर में कोई समस्या थी और मुझे निम्नानुसार ReplaceNamedGroup फ़ंक्शन में संशोधन करना पड़ा।

private static string ReplaceNamedGroup(string input, string groupName, string replacement, Match m) 
{ 
    string capture = m.Value; 
    capture = capture.Remove(m.Groups[groupName].Index - m.Index, m.Groups[groupName].Length); 
    capture = capture.Insert(m.Groups[groupName].Index - m.Index, replacement); 
    return capture; 
} 
+0

यह एक ही कोड दिखता है ... – JobaDiniz

+1

@JobaDiniz उन्होंने मेरा जवाब शामिल करने के लिए अपना जवाब संपादित किया। Https://stackoverflow.com/posts/13342795/revisions – Justin

0

@ user1817787 द्वारा मूल विधि का एक और संपादित संस्करण, यह एक नाम वाले समूह के कई उदाहरण का समर्थन करता है (यह भी शामिल है एक @Justin के लिए इसी तरह ठीक तैनात (रिटर्न {match.Index, मिलान का उपयोग परिणाम लम्बाई} {0, input.Length} के बजाय):

public static string ReplaceNamedGroup(
    string input, string groupName, string replacement, Match match) 
{ 
    var sb = new StringBuilder(input); 
    var matchStart = match.Index; 
    var matchLength = match.Length; 

    var captures = match.Groups[groupName].Captures.OfType<Capture>() 
     .OrderByDescending(c => c.Index); 

    foreach (var capt in captures) 
    { 
     if (capt == null) 
      continue; 

     matchLength += replacement.Length - capt.Length; 

     sb.Remove(capt.Index, capt.Length); 
     sb.Insert(capt.Index, replacement); 
    } 

    var end = matchStart + matchLength; 
    sb.Remove(end, sb.Length - end); 
    sb.Remove(0, matchStart); 

    return sb.ToString(); 
} 
+0

देखें यदि प्रतिस्थापन लंबाई कैप्चर की लंबाई से अलग है, तो यह पहले निकालने/डालने के बाद इंडेक्स को फेंक देगा। – user1620220

+0

@ user1620220 मैंने एकल वर्णों के साथ एकल पात्रों को प्रतिस्थापित किया जैसे उदाहरण 123 ==> 999. उदा। संवेदनशील डेटा मास्किंग के लिए। –

0

सरल समाधान मिलान समूहों को प्रतिस्थापन में संदर्भित करना है। तो उपसर्ग $1 है और पोस्टफिक्स $3 है।

मैं गया है नीचे दिए गए कोड का परीक्षण नहीं किया है, लेकिन एक regEx मैं हाल ही में लिखा है के लिए इसी तरह काम करना चाहिए:

string pattern = "^(?<PREFIX>abc_)(?<ID>[0-9])+(?<POSTFIX>_def)$"; 
string input = "abc_123_def"; 
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase); 
string replacement = String.Format("$1{0}$3", "456"); 
Console.WriteLine(regex.Replace(input, string.Format("${{PREFIX}}{0}${{POSTFIX}}", replacement))); 
1

मैं ReplaceNamedGroup छोटा है, अभी भी कई कैप्चर समर्थन।

private static string ReplaceNamedGroup(string input, string groupName, string replacement, Match m) 
{ 
    string result = m.Value; 
    foreach (Capture cap in m.Groups[groupName]?.Captures) 
    { 
    result = result.Remove(cap.Index - m.Index, cap.Length); 
    result = result.Insert(cap.Index - m.Index, replacement); 
    } 
return result; 
} 
-1

आप रेगुलर एक्सप्रेशन से के बारे में दस्तावेज़ देखने होंगे here

मैं इस बनाया गया एक नाम वाले समूह को बदलने के लिए बदलें। मैं समाधान का उपयोग नहीं कर सकता कि सभी समूहों के नाम पर लूप क्योंकि मेरे पास ऐसा मामला है जहां सभी अभिव्यक्तियों को समूहीकृत नहीं किया जाता है।

public static string ReplaceNamedGroup(this Regex regex, string input, string namedGroup, string value) 
    { 
     var replacement = Regex.Replace(regex.ToString(), 
      @"((?<GroupPrefix>\(\?)\<(?<GroupName>\w*)\>(?<Eval>.[^\)]+)(?<GroupPostfix>\)))", 
      @"${${GroupName}}").TrimStart('^').TrimEnd('$'); 
     replacement = replacement.Replace("${" + namedGroup + "}", value); 
     return Regex.Replace(input, regex.ToString(), replacement); 
    } 
संबंधित मुद्दे