Custom Regex Replacement in Java

谁说我不能喝 提交于 2021-01-27 06:17:26

问题


I want to find all patterns in a string that match the regex: no="(\d+)" then replace the digits in the group with something else.

In the method below I can find and replace the entire match, but that is not what I want. Is there a way to replace just a portion in that match?

private String replaceStringFromPatternSearch(String stringToSearch, String patternString, String replacementString) {
    String replacedString = null;
    Pattern stringPattern = Pattern.compile(patternString);

    Matcher stringMatcher = stringPattern.matcher(stringToSearch);
    replacedString = stringMatcher.replaceAll(replacementString);
    if (replacedString != null) {
        return replacedString;
    } else {
        return stringToSearch;
    }
}

回答1:


No Callbacks / Lambdas in Java Replace, But We Have Other Options

Option 1: Use Capture Buffers in Replacement Function

In replaceAll, you can build your replacement from components such as captured text and strings you want to insert at that time. Here is an example:

String replaced = yourString.replaceAll("no=\"(\\d+)\"", 
                                         "Something $1 Something else");

In the replacement, $1 are the captured digits. You don't have to use them, but as you can see you can build a replacement string around them.

Option 2 (Replacement Lambda/Callback/Delegate Equivalent): Build it One Match At a Time

In Java, to build even more sophisticated replacement, we don't have replacement lambdas, but we can do this:

StringBuffer resultString = new StringBuffer();
Pattern regex = Pattern.compile("no=\"(\\d+)\"");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
        // You can vary the replacement text for each match on-the-fly
        // String computed_replacement = .... Something wild!
        regexMatcher.appendReplacement(resultString, computed_replacement );
    } 
regexMatcher.appendTail(resultString);



回答2:


You could use lookarounds, so that the matches will only be the digits:

(?<=no=")\d+(?=")

Regular expression visualization

Debuggex Demo




回答3:


both of these methods solve my problem:

Example Data: <detail type="07" time="100611" no="07040365089" detail">

with the idea that I want to replace 07040365089 with something else. no="\d" occurs multiple times in the actual data. There are other replacements that are required for different patterns.

private String replaceStringFromPatternSearch2(String stringToSearch, String patternString, String replacementString) {
    String replacedString = "";
    Pattern stringPattern = Pattern.compile(patternString);
    int startSearch = 0;
    Matcher stringMatcher = stringPattern.matcher(stringToSearch);
    while (stringMatcher.find(startSearch)) {
        int start = stringMatcher.start(1);
        int end = stringMatcher.end(1);
        replacedString += stringToSearch.substring(startSearch, start) + replacementString + stringToSearch.substring(end);
        startSearch = end + 1;
    }
    if (!replacedString.isEmpty()) {
        return replacedString;
    } else {
        return stringToSearch;
    }
}

private String replaceStringFromPatternSearch(String stringToSearch, String patternString, String replacementString) {
    String replacedString = "";
    Pattern stringPattern = Pattern.compile(patternString);
    int startSearch = 0;
    Matcher stringMatcher = stringPattern.matcher(stringToSearch);
    StringBuffer sb = new StringBuffer();
    while (stringMatcher.find()) {
        String wholeGroup = stringMatcher.group(0);
        replacedString = wholeGroup.replace(stringMatcher.group(1), replacementString);
        stringMatcher.appendReplacement(sb, replacedString);
    }
    stringMatcher.appendTail(sb);
    if (sb.length() > 0) {
        return sb.toString();
    } else {
        return stringToSearch;
    }
}


来源:https://stackoverflow.com/questions/25052628/custom-regex-replacement-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!