2

I would like to replace text using a format something like this:

Text Input: (/ 5 6) + (/ 8 9) - (/ 12 3)
Pattern: (/ %s1 %s2)
Replacement: (%s1 / %s2)
Result: (5 / 6) + (8 / 9) - (12 / 3)

Is there a way to do this easily? I have looked through the Java API but couldn't find anything other than string formatting (which doesn't match patterns like this) and regular expressions (which don't let me use matched portions of the input as part of the output)

1

2 Answers 2

4

Try this:

String input = "(/ 5 6) + (/ 8 9) - (/ 12 3)";
String result = input.replaceAll("\\(/ (\\d+) (\\d+)\\)", "($1 / $2)");

This assumes that your %s groups are digits but it could easily be extended for more complex group patterns.

For more complicated replacements, you can inspect each matched pattern in code:

import java.util.regex.*;
Pattern pattern = Pattern.compile("\\(/ (\\d+) (\\d+)\\)");
Matcher m = pattern.matcher(input);
StringBuffer result = new StringBuffer();
while (m.find())
{
    String s1 = m.group(1);
    String s2 = m.group(2);
    // either:
    m.appendReplacement(result, "($1 / $2)");
    // or, for finer control:
    m.appendReplacement(result, "");
    result.append("(")
          .append(s1)
          .append(" / ")
          .append(s2)
          .append(")");
    // end either/or
}
m.appendTail(result);
return result.toString();

To handle more generalised patterns, look at @rolfl's answer to this question.

Sign up to request clarification or add additional context in comments.

Comments

3

A Regular Expression and the String.replaceAll(regex, replacement) is the answer.

Regexes are not for the feint of heart, but yours would be something like:

String result = input.replaceAll(
          "\\(\\s*(\\p{Punct})\\s+(\\d+)\\s+(\\d+)\\)",
          "($2 $1 $3)");

Edit.... Adrian's answer is 'about' the same as mine, and may suit you better. My answer assumes that the '/' character is any 'punctuation' character, and should be copied to the result, instead of only handling '/'.

Technically, you may want to replace \p{Punct} with something like [-+/*] (note that '-' must always come first) if you want just mathematical operators.

OK, working example:

    public static void main(String[] args) {
        String input = "(/ 5 6) + (/ 8 9) - (/ 12 3)";
        String regex = "\\(\\s*(\\p{Punct})\\s+(\\d+)\\s+(\\d+)\\)";
        String repl = "($2 $1 $3)";
        String output = input.replaceAll(regex, repl);
        System.out.printf("From: %s\nRegx: %s\nRepl: %s\nTo  : %s\n",
                input, regex, repl, output);
    }

Produces:

  From: (/ 5 6) + (/ 8 9) - (/ 12 3)
  Regx: \(\s*(\p{Punct})\s+(\d+)\s+(\d+)\)
  Repl: ($2 $1 $3)
  To  : (5 / 6) + (8 / 9) - (12 / 3)

2 Comments

You need to escape all of the inner slashes (change \s to \\s)
Now the outer ones have too many... Should be two slashes everywhere there is a slash. I think it should look like this. \\(\\s*(\\p{Punct})\\s+(\\d+)\\s+(\\d+)\\)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.