-1

I am working on adding search / replace functionality to an android application.

I would like the user to be able to search and replace using regular expressions. The search functionality works correctly, however a newline character in the replacement string \n is interpreted as a literal 'n'.

Here is what my code is doing:

Pattern.compile(search.getText().toString()).matcher(text).replaceAll(replace.getText().toString())

Given

  • text is a CharSequence with contents A \n\n\nB (note the trailing space after 'A')
  • search being a textbox with the contents \s+\n
  • replace being a text box with contents \n.

I expect the result of the code above to be text = A\n\n\nB (trailing spaces removed).

Instead the result is text = An\n\nB. i.e. the \n in the replace text box is interpreted as a literal 'n'.

I would like to know what I can do in order to read the contents of replace, such that the \n is interpreted as a newline.

Note that I can achieve the desired result in the example by capturing the newline like with search = \s+(\n) and replace = $1. This is not, however, the issue.

For the purposes of this discussion I am only considering Unix line endings.

Edit:

using replace contents = \\n results in a literal '\n' being inserted.

i.e.

A    


B

is transformed to

A\n

B
hs1
  • 51
  • 1
  • 4

2 Answers2

0

The approach suggested by Wiktor Stribiżew found in in stackoverflow.com/a/4298836 works for me.

Essentially, we need to parse the string and replace each escaped character with the correct escaped sequence.

Here is the code I used:

private String unescape(final String input) {
    final StringBuilder builder = new StringBuilder();
    boolean isEscaped = false;
    for (int i = 0; i < input.length(); i++) {
        char current = input.charAt(i);
        if (isEscaped) {
            if (current == 't') {
                builder.append('\t');
            } else if (current == 'b') {
                builder.append('\b');
            } else if (current == 'r') {
                builder.append('\r');
            } else if (current == 'n') {
                builder.append('\n');
            } else if (current == 'f') {
                builder.append('\f');
            } else if (current == '\\' || current == '\'' || current == '"') {
                builder.append(current);
            } else {
                throw new IllegalArgumentException("Illegal escape sequence.");
            }
            isEscaped = false;
        } else if (current == '\\') {
            isEscaped = true;
        } else {
            builder.append(current);
        }
    }
    return builder.toString();
}

It isn't as complete or as correct as the solution in the answer linked above, but it appears to work correctly for my purposes.

hs1
  • 51
  • 1
  • 4
-1

The issue here seems to be that '' is itself a special character. You have to double it for regex to see it as a necessary character. Doing a double replacement on all '' should proof useful. like this

     yourString = yourString.replace("\", "\\");
  • 1
    This does not seem to work. I have updated the question to reflect this. – hs1 Nov 06 '20 at 20:44
  • 1
    This can't work because it does not answer the current question. Namely, how to use a newline as a newline char in the literal text used as replacement pattern. – Wiktor Stribiżew Nov 06 '20 at 20:46