How can I find all "((" and replace them with "("? - java

I'm given a string, and I want to replace all open parenthesis that occur in succession, with a single one
((5)) → (5)
((((5)))) → (5)
I tried
str = str.replaceAll("((", "(");
and got regex patttern error
then i tried
str = str.replaceAll("\\((", "(");
then i tried
str = str.replaceAll("\\\\((", "(");
I keep getting the same error!

have you tried this?
str = str.replaceAll("\\({2,}", "(");
The '\' is the escape character, so every special character must be proceeded by it. Without them, regex reads it as an open parentheses used for grouping and expects a closed parentheses.
Edit: Originally, I thought he was trying to match exactly 2

You need to escape each parenthesis and add + to account for successive occurrences:
str = str.replaceAll("\\(\\(+","(");

Assuming the parentheses don't need to be paired, e.g. ((((5)) should become (5), then the following will do:
str = str.replaceAll("([()])\\1+", "$1");
Test
for (String str : new String[] { "(5)", "((5))", "((((5))))", "((((5))" }) {
str = str.replaceAll("([()])\\1+", "$1");
System.out.println(str);
}
Output
(5)
(5)
(5)
(5)
Explanation
( Start capture group
[()] Match a '(' or a ')'. In a character class, '(' and ')'
has no special meaning, so they don't need to be escaped
) End capture group, i.e. capture the matched '(' or ')'
\1+ Match 1 or more of the text from capture group #1. As a
Java string literal, the `\` was escaped (doubled)
$1 Replace with the text from capture group #1
See also regex101.com for demo.

I am not sure if the brackets are fixed or dynamic but assuming they may be dynamic what you could do here is use replaceAll and then use String.Format to format the string.
Hope it helps
public class HelloWorld{
public static void main(String []args){
String str = "((((5))))";
String abc = str.replaceAll("\\(", "").replaceAll("\\)","");
abc = String.format("(%s)", abc);
System.out.println(abc);
}
}
Output: (5)
I have tried the above code with ((5)) and (((5))) and it produces the same output.

Related

Replace all characters between two delimiters using regex

I'm trying to replace all characters between two delimiters with another character using regex. The replacement should have the same length as the removed string.
String string1 = "any prefix [tag=foo]bar[/tag] any suffix";
String string2 = "any prefix [tag=foo]longerbar[/tag] any suffix";
String output1 = string1.replaceAll(???, "*");
String output2 = string2.replaceAll(???, "*");
The expected outputs would be:
output1: "any prefix [tag=foo]***[/tag] any suffix"
output2: "any prefix [tag=foo]*********[/tag] any suffix"
I've tried "\\\\\[tag=.\*?](.\*?)\\\\[/tag]" but this replaces the whole sequence with a single "\*".
I think that "(.\*?)" is the problem here because it captures everything at once.
How would I write something that replaces every character separately?
you can use the regex
\w(?=\w*?\[)
which would match all characters before a "[\"
see the regex demo, online compiler demo
You can capture the chars inside, one by one and replace them by * :
public static String replaceByStar(String str) {
String pattern = "(.*\\[tag=.*\\].*)\\w(.*\\[\\/tag\\].*)";
while (str.matches(pattern)) {
str = str.replaceAll(pattern, "$1*$2");
}
return str;
}
Use like this it will print your tx2 expected outputs :
public static void main(String[] args) {
System.out.println(replaceByStar("any prefix [tag=foo]bar[/tag] any suffix"));
System.out.println(replaceByStar("any prefix [tag=foo]loooongerbar[/tag] any suffix"));
}
So the pattern "(.*\\[tag=.*\\].*)\\w(.*\\[\\/tag\\].*)" :
(.*\\[tag=.*\\].*) capture the beginning, with eventually some char in the middle
\\w is for the char you want to replace
(.*\\[\\/tag\\].*) capture the end, with eventually some char in the middle
The substitution $1*$2:
The pattern is (text$1)oneChar(text$2) and it will replace by (text$1)*(text$2)

word extraction and splitting using Java regex

I have a string "'GLO', FLO" Now, I want a regex expression that will check each words in the string and if:
-word begins and ends with a single quote, replace single quotes with spaces
-if a comma is encounted between words split both words using space.
so, in the end, I should get GLO FLO.
Any help on how to do this using replaceAll() method on the string?
This regex didn't do it for me : "'([^' ]+)|\\s+'"
public static void displaySplitString(final String str) {
String pattern1 = "^'?(\\w+)'?,\\s+(\\w+)$";
StringTokenizer strTok = new StringTokenizer(str, " , ");
while (strTok.hasMoreTokens()) {
String delim = (strTok.nextToken());
delim.replaceAll(pattern1, "$1$2");
System.out.println(delim);
}
} //in main method displaySplitString("'GLO', FLO");
Here is the snippet that should get you going:
public static void displaySplitString(String str)
{
String pattern1 = "^'?(\\w+)'?(?=\\S)";
str = str.replaceAll(pattern1, " $1 ");
StringTokenizer strTok = new StringTokenizer(str, " , ");
while (strTok.hasMoreTokens())
{
String delim = (strTok.nextToken());
System.out.println(delim);
}
}
Here,
I change str argument declaration as not final (so that we could change the str value inside the method)
I am using the first regex ^'?(\\w+)'?(?=\\S) to remove potential single quotes from around the first word
Since you use a StringTokenizer, just 2 lines inside the while block are enough.
The regex means:
^ - Start looking for the match at the very start of the string
'? - match 0 or 1 single quote
(\\w+) - match and capture 1 or more alphanumeric symbols (we'll refer to them as $1 in the replacement pattern)
'? - match 0 or 1 single quote
(?=\\S) - match only if there is no space after the optional single quote. Perhaps, you can even replace this lookahead with a mere , if you always have it there, after the first word.

Insert character before specific character Java

I have been taking a look at the regular expressions and how to use it in Java for the problem I have to solve. I have to insert a \ before every ". This is what I have:
public class TestExpressions {
public static void main (String args[]) {
String test = "$('a:contains(\"CRUCERO\")')";
test = test.replaceAll("(\")","$1%");
System.out.println(test);
}
}
The ouput is:
$('a:contains("%CRUCERO"%)')
What I want is:
$('a:contains(\"CRUCERO\")')
I have changed % for \\ but have an error StringIndexOutofBounds don't know why. If someone can help me I would appreciate it, thank you in advance.
I have to insert a \ before every "
You can try with replace which automatically escapes all regex metacharacters and doesn't use any special characters in replacement part so you can simply use String literals you want to be put in matched part.
So lets just replace " with \" literal. You can write it as
test = test.replace("\"", "\\\"");
If you want to insert backspace before quote then use:
test = test.replaceAll("(\")","\\\\$1"); // $('a:contains(\"CRUCERO\")')
Or if you want to avoid already escaped quote then use negative lookbehind:
String test = "$('a:contains(\\\"CRUCERO\")')";
test = test.replaceAll("((?<!\\\\)\")","\\\\$1"); // $('a:contains(\"CRUCERO\")')
String result = subject.replaceAll("(?i)\"CRUCERO\"", "\\\"CRUCERO\\\"");
EXPLANATION:
Match the character string “"CRUCERO"” literally (case insensitive) «"CRUCERO"»
Ignore unescaped backslash «\»
Insert the character string “"CRUCERO” literally «"CRUCERO»
Ignore unescaped backslash «\»
Insert the character “"” literally «"»
If your goal is escape text for Java strings, then instead of regular expressions, consider using
String escaped = org.apache.commons.lang.StringEscapeUtils.
escapeJava("$('a:contains(\"CRUCERO\")')");
System.out.println(escaped);
Output:
$('a:contains(\"CRUCERO\")')
JavaDoc: http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringEscapeUtils.html#escapeJava(java.lang.String)

Regular Expression - inserting space after comma only if succeeded by a letter or number

In Java I want to insert a space after a String but only if the character after the comma is succeeded by a digit or letter. I am hoping to use the replaceAll method which uses regular expressions as a parameter. So far I have the following:
String s1="428.0,chf";
s1 = s1.replaceAll(",(\\d|\\w)",", ");
This code does successfully distinguish between the String above and one where there is already a space after the comma. My problem is that I can't figure out how to write the expression so that the space is inserted. The code above will replace the c in the String shown above with a space. This is not what I want.
s1 should look like this after executing the replaceAll: "428.0 chf"
s1.replaceAll(",(?=[\da-zA-Z])"," ");
(?=[\da-zA-Z]) is a positive lookahead which would look for a digit or a word after ,.This lookahead would not be replaced since it is never included in the result.It's just a check
NOTE
\w includes digit,alphabets and a _.So no need of \d.
A better way to represent it would be [\da-zA-Z] instead of \w since \w also includes _ which you do not need 2 match
Try this, and note that $1 refers to your matched grouping:
s1.replaceAll(",(\\d|\\w)"," $1");
Note that String.replaceAll() works in the same way as a Matcher.replaceAll(). From the doc:
The replacement string may contain references to captured subsequences
String s1="428.0,chf";
s1 = s1.replaceAll(",([^_]\\w)"," $1"); //Match alphanumeric except '_' after ','
System.out.println(s1);
Output: -
428.0 chf
Since \w matches digits, words, and an underscore, So, [^_] negates the underscore from \w..
$1 represents the captured group.. You captured c after , here, so replace c with _$1 -> _c.. "_" represent a space..
Try this....
public class Tes {
public static void main(String[] args){
String s1="428.0,chf";
String[] sArr = s1.split(",");
String finalStr = new String();
for(String s : sArr){
finalStr = finalStr +" "+ s;
}
System.out.println(finalStr);
}
}

Regular expression to match unescaped special characters only

I'm trying to come up with a regular expression that can match only characters not preceded by a special escape sequence in a string.
For instance, in the string Is ? stranded//? , I want to be able to replace the ? which hasn't been escaped with another string, so I can have this result : **Is Dave stranded?**
But for the life of me I have not been able to figure out a way. I have only come up with regular expressions that eat all the replaceable characters.
How do you construct a regular expression that matches only characters not preceded by an escape sequence?
Use a negative lookbehind, it's what they were designed to do!
(?<!//)[?]
To break it down:
(
?<! #The negative look behind. It will check that the following slashes do not exist.
// #The slashes you are trying to avoid.
)
[\?] #Your special charactor list.
Only if the // cannot be found, it will progress with the rest of the search.
I think in Java it will need to be escaped again as a string something like:
Pattern p = Pattern.compile("(?<!//)[\\?]");
Try this Java code:
str="Is ? stranded//?";
Pattern p = Pattern.compile("(?<!//)([?])");
m = p.matcher(str);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, m.group(1).replace("?", "Dave"));
}
m.appendTail(sb);
String s = sb.toString().replace("//", "");
System.out.println("Output: " + s);
OUTPUT
Output: Is Dave stranded?
I was thinking about this and have a second simplier solution, avoiding regexs. The other answers are probably better but I thought I might post it anyway.
String input = "Is ? stranded//?";
String output = input
.replace("//?", "a717efbc-84a9-46bf-b1be-8a9fb714fce8")
.replace("?", "Dave")
.replace("a717efbc-84a9-46bf-b1be-8a9fb714fce8", "?");
Just protect the "//?" by replacing it with something unique (like a guid). Then you know any remaining question marks are fair game.
Use grouping. Here's one example:
import java.util.regex.*;
class Test {
public static void main(String[] args) {
Pattern p = Pattern.compile("([^/][^/])(\\?)");
String s = "Is ? stranded//?";
Matcher m = p.matcher(s);
if (m.matches)
s = m.replaceAll("$1XXX").replace("//", "");
System.out.println(s + " -> " + s);
}
}
Output:
$ java Test
Is ? stranded//? -> Is XXX stranded?
In this example, I'm:
first replacing any non-escaped ? with "XXX",
then, removing the "//" escape sequences.
EDIT Use if (m.matches) to ensure that you handle non-matching strings properly.
This is just a quick-and-dirty example. You need to flesh it out, obviously, to make it more robust. But it gets the general idea across.
Match on a set of characters OTHER than an escape sequence, then a regex special character. You could use an inverted character class ([^/]) for the first bit. Special case an unescaped regex character at the front of the string.
String aString = "Is ? stranded//?";
String regex = "(?<!//)[^a-z^A-Z^\\s^/]";
System.out.println(aString.replaceAll(regex, "Dave"));
The part of the regular expression [^a-z^A-Z^\\s^/] matches non-alphanumeric, whitespace or non-forward slash charaters.
The (?<!//) part does a negative lookbehind - see docco here for more info
This gives the output Is Dave stranded//?
try matching:
(^|(^.)|(.[^/])|([^/].))[special characters list]
I used this one:
((?:^|[^\\])(?:\\\\)*[ESCAPABLE CHARACTERS HERE])
Demo: https://regex101.com/r/zH1zO3/4

Categories

Resources