मैं यहां किसी भी समाधान से काफी संतुष्ट नहीं था। मैं एक स्टेटलेस समाधान चाहता था। और अगर मैं प्रतिस्थापन स्ट्रिंग पैटर्न से मेल खाने के लिए हुआ तो मैं एक अनंत लूप में समाप्त नहीं होना चाहता था। जबकि मैं उस पर था, मैंने limit
पैरामीटर के लिए समर्थन जोड़ा और count
पैरामीटर लौटा दिया।(मैंने संदर्भ द्वारा एक पूर्णांक गुजरने के अनुकरण के लिए AtomicInteger
का उपयोग किया था।) मैंने अज्ञात वर्ग को परिभाषित करना आसान बनाने के लिए, पैरामीटर सूची के अंत में callback
पैरामीटर को स्थानांतरित किया।
final Map<String,String> props = new HashMap<String,String>();
props.put("MY_NAME", "Kip");
props.put("DEPT", "R&D");
props.put("BOSS", "Dave");
String subjectString = "Hi my name is ${MY_NAME} and I work in ${DEPT} for ${BOSS}";
String sRegex = "\\$\\{([A-Za-z0-9_]+)\\}";
String replacement = ReplaceCallback.replace(sRegex, subjectString, new ReplaceCallback.Callback() {
public String matchFound(MatchResult match) {
String group1 = match.group(1);
if(group1 != null && props.containsKey(group1))
return props.get(group1);
return match.group();
}
});
System.out.println("replacement: " + replacement);
यहाँ और ReplaceCallback वर्ग की मेरी संस्करण है:
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.*;
public class ReplaceCallback
{
public static interface Callback {
/**
* This function is called when a match is made. The string which was matched
* can be obtained via match.group(), and the individual groupings via
* match.group(n).
*/
public String matchFound(MatchResult match);
}
/**
* Replaces with callback, with no limit to the number of replacements.
* Probably what you want most of the time.
*/
public static String replace(String pattern, String subject, Callback callback)
{
return replace(pattern, subject, -1, null, callback);
}
public static String replace(String pattern, String subject, int limit, Callback callback)
{
return replace(pattern, subject, limit, null, callback);
}
/**
* @param regex The regular expression pattern to search on.
* @param subject The string to be replaced.
* @param limit The maximum number of replacements to make. A negative value
* indicates replace all.
* @param count If this is not null, it will be set to the number of
* replacements made.
* @param callback Callback function
*/
public static String replace(String regex, String subject, int limit,
AtomicInteger count, Callback callback)
{
StringBuffer sb = new StringBuffer();
Matcher matcher = Pattern.compile(regex).matcher(subject);
int i;
for(i = 0; (limit < 0 || i < limit) && matcher.find(); i++)
{
String replacement = callback.matchFound(matcher.toMatchResult());
replacement = Matcher.quoteReplacement(replacement); //probably what you want...
matcher.appendReplacement(sb, replacement);
}
matcher.appendTail(sb);
if(count != null)
count.set(i);
return sb.toString();
}
}
में दो कुत्तों मैं वास्तव में लौटे स्ट्रिंग और अनुक्रमित कतार के साथ बेहतर अपने मूल जवाब चाहते: ४६५१०४०३२१० वापसी मान का उत्पादन करेगा। फिर उन्हें विपरीत में लागू करना। इस तरह से सरल है, लेकिन लगता है कि प्रत्येक मैच के लिए पूरी स्ट्रिंग को पुन: स्कैन करने के लिए और अधिक काम करना प्रतीत होता है। सलाह के लिये धन्यवाद! – Mike
मैंने मूल सुझाव को वापस जोड़ा। अपेक्षित इनपुट आकार इस बात को लेकर अंतर करेगा कि फिर से बदलना या कतार बदलना अधिक प्रभावी होगा या नहीं। मुझे लगता है कि प्रतिस्थापन स्ट्रिंग के साथ प्रतिस्थापन विधि कतार भी हो सकती है ... – jdmichal
एरर ... मिस्पाक। स्पष्ट रूप से सीपीयू समय के संबंध में क्यूईइंग हमेशा अधिक प्रभावी होती है। अंतर यह होगा कि चिंता करने के लिए यह एक बड़ी समस्या है या नहीं। – jdmichal