Vimsucks
Vimsucks

Reputation: 33

How to replace all double quotes without a backslash ahead

Assume I have a string like below:

String param = "[\"\\n\",\"\\t\",\"'\",\"\\\"\",\"\\\\\"]"

The output of System.out.println is:

"\n","\t","'","\"","\\"

I would like to replace double quotes which doesn't have a backslash ahead, or, in another word, I would like to have the System.out.println output like below:

\n,\t,',\",\\

So I used this pattern:

System.out.println(param.replaceAll("\\\\{0}\"", ""));

But I got this:

\n,\t,',\,\\

As you can see, the double quote with a backslash ahead is also replaced. How can I prevent it from being replaced?

Edit: Sorry about the square brackets. You may ignore them cause they have nothing to do with this question

Upvotes: 3

Views: 1634

Answers (4)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626738

You can use the following regex to match and remove " that are string literal qualifiers:

(?s)(?<!\\)((?:\\{2})*)"([^"\\]*(?:\\.[^"\\]*)*)"

See the regex demo.

Details

  • (?s) - DOTALL modifier (just in case the string literal can span across lines)
  • (?<!\\) - no \ immediately to the left of the current location
  • ((?:\\{2})*) - Group 1: any 0+ conseuctive occurrences of 2 backslashes
  • " - a double quote (string literal start)
  • ([^"\\]*(?:\\.[^"\\]*)*) - Group 2:
    • [^"\\]* - any 0+ chars other than \ and "
    • (?:\\.[^"\\]*)* - 0+ sequences of
      • \\. - a \ followed with any char
      • [^"\\]* - any 0+ chars other than \ and "
  • " - a closing string literal double quote

See the Java demo:

String param = "[\"\\n\",\"\\t\",\"'\",\"\\\"\",\"\\\\\",\"\\\\\\\"\"]";
System.out.println(param);
// => ["\n","\t","'","\"","\\","\\\""]
String regex = "(?s)(?<!\\\\)((?:\\\\{2})*)\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"";
param = param.replaceAll(regex, "$1$2");
System.out.println(param);
// => [\n,\t,',\",\\,\\\"]

Upvotes: 2

gezdy
gezdy

Reputation: 3322

use just that for your code :

System.out.println(param.replaceAll("\"(.)\"", "$1").replaceAll("\\[\"(.*)\"\\]", "$1"));

Your string:

String param = "[\"\\n\",\"\\t\",\"'\",\"\\\"\",\"\\\\\"]";

All items are between double quotes. So the first replaceAll will replace quotes :

System.out.println(param.replaceAll("\"(.)\"", "$1"));

The output:

["\n,\t,',\",\\"]

To clean the start and end of string:

System.out.println(param.replaceAll("\"(.)\"", "$1").replaceAll("\\[\"(.*)\"\\]", "$1"));

Upvotes: 0

Sweeper
Sweeper

Reputation: 270995

You need to match a back slash with a negative lookbehind.

A negative lookbehind looks like this:

(?<!X)Y

It will match pattern Y only if pattern X does not exist immediately before pattern Y.

In your case, X is "a back slash without a backslash in front" and Y is ".

This is the regex you need:

(?<![^\\]\\)"

Java code:

System.out.println(param.replaceAll("(?<![^\\\\]\\\\)\"", ""));

By the way, you seem to have forgotten to remove the leading and trailing square brackets.

Upvotes: 1

Gurmanjot Singh
Gurmanjot Singh

Reputation: 10360

Use this Regex:

"([^,]+)"

Click for Demo

Try this code(Generated):

import java.util.regex.Matcher;
import java.util.regex.Pattern;

final String regex = "\"([^,]+)\"";
final String string = "[\"\\n\",\"\\t\",\"'\",\"\\\"\",\"\\\\\"]";
final String subst = "$1";

final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);

// The substituted value will be contained in the result variable
final String result = matcher.replaceAll(subst);

System.out.println("Substitution result: " + result);

Execute and See the Output here

Upvotes: 1

Related Questions