Find and Replace a pattern of string in java - java

I use regex and string replaceFirst to replace the patterns as below.
String xml = "<param>otpcode=1234567</param><param>password=abc123</param>";
if(xml.contains("otpcode")){
Pattern regex = Pattern.compile("<param>otpcode=(.*)</param>");
Matcher matcher = regex.matcher(xml);
if (matcher.find()) {
xml = xml.replaceFirst("<param>otpcode=" + matcher.group(1)+ "</param>","<param>otpcode=xxxx</param>");
}
}
System.out.println(xml);
if (xml.contains("password")) {
Pattern regex = Pattern.compile("<param>password=(.*)</param>");
Matcher matcher = regex.matcher(xml);
if (matcher.find()) {
xml = xml.replaceFirst("<param>password=" + matcher.group(1)+ "</param>","<param>password=xxxx</param>");
}
}
System.out.println(xml);
Desired O/p
<param>otpcode=xxxx</param><param>password=abc123</param>
<param>otpcode=xxxx</param><param>password=xxxx</param>
Actual o/p (Replaces the entire string in a single shot in first IF itself)
<param>otpcode=xxxx</param>
<param>otpcode=xxxx</param>

You need to do a non-greedy regex:
<param>otpcode=(.*?)</param>
<param>password=(.*?)</param>
This will match up to the first </param> not the last one...

Related

Match everything after and before something regex Java

Here is my code:
String stringToSearch = "https://example.com/excludethis123456/moretext";
Pattern p = Pattern.compile("(?<=.com\\/excludethis).*\\/"); //search for this pattern
Matcher m = p.matcher(stringToSearch); //match pattern in StringToSearch
String store= "";
// print match and store match in String Store
if (m.find())
{
String theGroup = m.group(0);
System.out.format("'%s'\n", theGroup);
store = theGroup;
}
//repeat the process
Pattern p1 = Pattern.compile("(.*)[^\\/]");
Matcher m1 = p1.matcher(store);
if (m1.find())
{
String theGroup = m1.group(0);
System.out.format("'%s'\n", theGroup);
}
I want to to match everything that is after excludethis and before a / that comes after.
With "(?<=.com\\/excludethis).*\\/" regex I will match 123456/ and store that in String store. After that with "(.*)[^\\/]" I will exclude / and get 123456.
Can I do this in one line, i.e combine these two regex? I can't figure out how to combine them.
Just like you have used a positive look behind, you can use a positive look ahead and change your regex to this,
(?<=.com/excludethis).*(?=/)
Also, in Java you don't need to escape /
Your modified code,
String stringToSearch = "https://example.com/excludethis123456/moretext";
Pattern p = Pattern.compile("(?<=.com/excludethis).*(?=/)"); // search for this pattern
Matcher m = p.matcher(stringToSearch); // match pattern in StringToSearch
String store = "";
// print match and store match in String Store
if (m.find()) {
String theGroup = m.group(0);
System.out.format("'%s'\n", theGroup);
store = theGroup;
}
System.out.println("Store: " + store);
Prints,
'123456'
Store: 123456
Like you wanted to capture the value.
This may be useful for you :)
String stringToSearch = "https://example.com/excludethis123456/moretext";
Pattern pattern = Pattern.compile("excludethis([\\d\\D]+?)/");
Matcher matcher = pattern.matcher(stringToSearch);
if (matcher.find()) {
String result = matcher.group(1);
System.out.println(result);
}
If you don't want to use regex, you could just try with String::substring*
String stringToSearch = "https://example.com/excludethis123456/moretext";
String exclusion = "excludethis";
System.out.println(stringToSearch.substring(stringToSearch.indexOf(exclusion)).substring(exclusion.length(), stringToSearch.substring(stringToSearch.indexOf(exclusion)).indexOf("/")));
Output:
123456
* Definitely don't actually use this

Regex Pattern to Split Word in A string Using An Identifier

I would like to split the following string by commas using a DOTALL regex pattern what will accept letters, numbers, whitespaces and special characters such as underscores and asterisks i.e. #input("Test_1, Test_TWO , TEST_THIRTY_3*") so the output would look like:
"Test_1",
"Test_TWO",
"TEST_THIRTY_3*"
public static void main(String args[])
{
String line = "#input(\"Test_1,Test_TWO , TEST_THIRTY_3*\"\\)\";
String pattern = "#input(\"(.*?)\".*";
Pattern r = Pattern.compile(pattern, Pattern.DOTALL);
Matcher m = r.matcher(line);
while (m.find()) {
System.out.println("Found word: " + m.group(1) );
}
You have to escape the ( by \( so your regex should look like this #input\(\"(.*?)\".*, second you can use \s*,\s* to split the result like this :
String line = "#input(\"Test_1,Test_TWO , TEST_THIRTY_3*\"\\)";
String pattern = "#input\\(\"(.*?)\".*";
Pattern r = Pattern.compile(pattern, Pattern.DOTALL);
Matcher m = r.matcher(line);
while (m.find()) {
System.out.println(Arrays.toString(m.group(1).split("\\s*,\\s*")));
//----------------------------------------------------^^^^^^^^
}
outputs
[Test_1, Test_TWO, TEST_THIRTY_3*]
If you do not have to stick to regex you might just take the string methods.
List<String> output = Arrays.asList(line.split(","));

Regular expression in Java?

I have below string:
String line = put retur#ERns between #errf #fgrf#re paragraphs #fg^%tg2#785Ty*;
How can I get below values with regex:
#ERns
#errf
#fgrf
#re
#fg^%tg2
#785Ty*
My code:
String pattern = "^#\S+";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
while (m.find()) {
Log.i("log", m.group());
}
You can use this regex instead:
#[^#\s]*
RegEx Demo
Negated character class [^#\s] matches a character that is not # and not a whitespace.
In Java use:
final String pattern = "#[^#\\s]*";

Replace different Regex-Matches with Match-based results in Java

One common usage for regex is the replacement of the matches with something that is based on the matches.
For example a commit-text with ticket numbers ABC-1234: some text (ABC-1234) has to be replaced with <ABC-1234>: some text (<ABC-1234>) (<> as example for some surroundings.)
This is very simple in Java
String message = "ABC-9913 - Bugfix: Some text. (ABC-9913)";
String finalMessage = message;
Matcher matcher = Pattern.compile("ABC-\\d+").matcher(message);
if (matcher.find()) {
String ticket = matcher.group();
finalMessage = finalMessage.replace(ticket, "<" + ticket + ">");
}
System.out.println(finalMessage);
results in<ABC-9913> - Bugfix: Some text. (<ABC-9913>).
But if there are different matches in the input String, this is different. I tried a slightly different code replacing if (matcher.find()) { with while (matcher.find()) {. The result is messed up with doubled replacements (<<ABC-9913>>).
How can I replace all matching values in an elegant way?
You can simply use replaceAll:
String input = "ABC-1234: some text (ABC-1234)";
System.out.println(input.replaceAll("ABC-\\d+", "<$0>"));
prints:
<ABC-1234>: some text (<ABC-1234>)
$0 is a reference to the matched string.
Java regex reference (see "Groups and capturing").
The problem is that the replace() method transforms the string over and over again.
A better way is to replace one match at a time. The matcher class has an appendReplacement-method for this.
String message = "ABC-9913, ABC-9915 - Bugfix: Some text. (ABC-9913,ABC-9915)";
Matcher matcher = Pattern.compile("ABC-\\d+").matcher(message);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String ticket = matcher.group();
matcher.appendReplacement(sb, "<" + ticket + ">");
}
matcher.appendTail(sb);
System.out.println(sb);

regex extract string between two characters

I would like to extract the strings between the following characters in the given string using regex in Java:
/*
1) Between \" and \" ===> 12222222222
2) Between :+ and # ===> 12222222222
3) Between # and > ===> 192.168.140.1
*/
String remoteUriStr = "\"+12222222222\" <sip:+12222222222#192.168.140.1>";
String regex1 = "\"(.+?)\"";
String regex2 = ":+(.+?)#";
String regex3 = "#(.+?)>";
Pattern p = Pattern.compile(regex1);
Matcher matcher = p.matcher(remoteUri);
if (matcher.matches()) {
title = matcher.group(1);
}
I am using the above given code snippet, its not able to extract the strings that I want it to. Am I doing anything wrong? Meanwhile, I am quite new to regex.
The matches() method attempts to match the regular expression against the entire string. If you want to match a part of the string, you want the find() method:
if (matcher.find())
You could, however, build a single regular expression to match all three parts at once:
String regex = "\"(.+?)\" \\<sip:\\+(.+?)#(.+?)\\>";
Pattern p = Pattern.compile(regex);
Matcher matcher = p.matcher(remoteUriStr);
if (matcher.matches()) {
title = matcher.group(1);
part2 = matcher.group(2);
ip = matcher.group(3);
}
Demo: http://ideone.com/8t2EC
If your input always looks like that and you always want the same parts from it you can put that in a single regex (with multiple capturing groups):
"([^"]+)" <sip:([^#]+)#([^>]+)>
So you can then use
Pattern p = Pattern.compile("\"([^\"]+)\" <sip:([^#]+)#([^>]+)>");
Matcher m = p.matcher(remoteUri);
if (m.find()) {
String s1 = m.group(1);
String s2 = m.group(2);
String s3 = m.group(3);
}

Categories