Let's say I have a String
String link = "www.thisisalink.com/tick1=#tick1#&tick2=#tick2#&tick3=#tick3#&tick4=#tick4#";
Then I can use
link = replaceFirst("(.+)=#\\1#", "");
To make it
link = "www.thisisalink.com/&tick2=#tick2#&tick3=#tick3#&tick4=#tick4#";
But I want to loop though the String, to get what has been replace and save it somewhere else, like a linked list or an array... result would be:
String[] result = ["tick1=#tick1#", "tick2=#tick2#", "tick3=#tick3#", "tick4=#tick4#"];
String link = "www.thisisalink.com/&&&";
But how can I do this? I tried looping with
while (link.matches("(.+)=#\\1#")){}
Which didn't work.
You can use Pattern Matcher classes to iterate over your string to find substrings that will match your regex. Then to replace founded substring you can use appednReplacement and appendTail. To get founded match you can use group() from Matcher instance.
Here is something similar to what you want
String link = "www.thisisalink.com/tick1=#tick1#&tick2=#tick2#&tick3=#tick3#&tick4=#tick4#";
StringBuffer sb = new StringBuffer();
Pattern p = Pattern.compile("(.+)=#\\1#");
Matcher m = p.matcher(link);
List<String> replaced = new ArrayList<>();
while (m.find()) {
m.appendReplacement(sb, "");
replaced.add(m.group());
}
m.appendTail(sb);
//to replace link with String stored in sb use link=sb.toString();
//otherwise link will be unchanged
System.out.println(sb);
System.out.println(replaced);
output:
www.thisisalink.com/&&&
[tick1=#tick1#, tick2=#tick2#, tick3=#tick3#, tick4=#tick4#]
This produces the Strings you want:
public static void main(String[] args)
{
final String link = "www.thisisalink.com/tick1=#tick1#&tick2=#tick2#&tick3=#tick3#&tick4=#tick4#";
final int index = link.indexOf("/") + 1;
final String[] result = link.substring(index).split("&");
final String newLink = link.substring(0, index) + repeat("&", result.length -1);
System.out.println(newLink);
for(final String tick : result)
{
System.out.println(tick);
}
}
private static String repeat(final String toRepeat, final int repetitions)
{
final StringBuilder sb = new StringBuilder(repetitions);
for(int i = 0; i < repetitions; i++)
{
sb.append(toRepeat);
}
return sb.toString();
}
Produces:
www.thisisalink.com/&&&
tick1=#tick1#
tick2=#tick2#
tick3=#tick3#
tick4=#tick4#
Related
I have a requirement to replace all the character within a string to lower case if it is followed by some string like "is".
For example:
String a = "name=xyz,isSalaried=Y,address=abc,isManager=N,salary=1000";
it should get converted to
"name=xyz,salaried=Y,address=abc,manager=N,salary=1000"
I am not very good at regular expression but I think can use it to achieve the required output.
It will be great if someone can help me out.
Your solution requires basic understanding of String and String methods in java.
Here is one working example. Although, it might not be the most efficient one.
NOTE:- YOU ASKED FOR A REGEX SOLUTION.BUT THIS IS USING PURE STRING METHODS
public class CheckString{
public static void main(String[] ar){
String s = "name=xyz,isSalaried=Y,address=abc,isManager=N,salary=1000";
String[] arr = s.split(",");
String ans = "";
int i = 0;
for(String text : arr){
int index = text.indexOf("=");
String before = text.substring(0,index).replace("is","").toLowerCase();
String after = text.substring(index);
if(i!=(arr.length-1)){
ans += before + after + ",";
i++;
}
else{
ans += before + after;
}
}
System.out.println(ans);
}
}
Try this.
first match the string and replace in a loop
String a = "name=xyz,isSalaried=Y,address=abc,isManager=N,salary=1000";
Matcher matcher = Pattern.compile("is(.*?)=").matcher(a);//.matcher(a).replaceAll(m -> m.group(1).toLowerCase());
while (matcher.find()) {
String matchedString = matcher.group(1);
a = a.replace("is"+matchedString,matchedString.toLowerCase());
}
System.out.printf(a);
I have the following class.
public class TestStringRegex {
public static void main(String[] args) {
StringBuilder text = new StringBuilder("KALAKA");
String wordToFind = "KA";
Pattern word = Pattern.compile(wordToFind);
Matcher match = word.matcher(text);
while (match.find()) {
System.out.println(match.end());
text=text.insert(match.end(),"INSERT");
}
System.out.println(text);
}
Expecting output to be KAINSERTLAKAINSERT.
But getting KAINSERTLAKA.
Is matcher/insert works on the length of input text?How to get desired output.
If you want to do it using matcher use the overloaded method with int i.e. matcher.find(index). For some reason mathcher.find() is not working as given in docs. If you are curious you need to debug the code.
Just say like below
int end = 0;
while (match.find(end)) {
end = match.end();
System.out.println(end);
text=text.insert(end,"INSERT");
}
Better way of doing the same will be
public static void main(String[] args) {
System.out.println("KALAKA".replaceAll("KA", "$0INSERT"));
}
That's all the code you need to write.
Use matcher.find(int startIndex) instead of find(). And update startIndex after each match. Full code:
public static void main(String[] args) {
StringBuilder text = new StringBuilder("KALAKA");
String wordToFind = "KA";
Pattern word = Pattern.compile(wordToFind);
Matcher match = word.matcher(text);
int findIndex = 0;
while (match.find(findIndex)) {
int end = match.end();
findIndex = end;
text = text.insert(end, "INSERT");
}
System.out.println(text);
}
Each next find() starts at the end of previous match
This works fine..!!!
public static void main(String[] args) {
StringBuilder text = new StringBuilder("KALAKA");
String wordToFind = "KA";
Pattern word = Pattern.compile(wordToFind);
Matcher match = word.matcher(text);
int end = 0;
while (match.find(end)) {
end = match.end();
text=text.insert(match.end(),"INSERT");
}
System.out.println(text);
}
I have the following String
"12:00:00, 2:30:003:45:00,23:45:00";
I have to update the string to use the following format:
"12:00:00, 2:30:00 |3:45:00,23:45:00 ";
I am able to split each string, but I do not know how to generate the required format. Here is the code I've written so far:
final String s = "12:00:00, 2:30:003:45:00,23:45:00";
final Pattern p = Pattern.compile("\\s*(\\d+:\\d\\d:\\d\\d)");
final Matcher m = p.matcher(s);
final List<String> tokens = new ArrayList<String>();
while (m.find()) {
tokens.add(m.group(1));
}
for (String tok : tokens) {
System.out.printf("[%s]%n", tok);
}
How about this:
final String string = "12:00:00, 2:30:003:45:00,23:45:00";
final Pattern pattern = Pattern.compile("\\s*(\\d+:\\d\\d:\\d\\d)");
final Matcher matcher = pattern.matcher(string);
final List<String> tokens = new ArrayList<String>();
while (matcher.find()) {
tokens.add(matcher.group(1));
}
System.out.println("tokens = " + tokens);
StringBuilder formattedString = new StringBuilder();
formattedString.append(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) {
if (i % 2 == 0) {
formattedString.append(" | ");
} else {
formattedString.append(", ");
}
formattedString.append(tokens.get(i));
}
System.out.println(formattedString);
Edit: I've updated it to use a for loop when constructing the formatted string based on the comments I've read.
If you want to add | after two dates separated by comma your code can look like
final String s = "12:00:00, 2:30:003:45:00,23:45:00";
final Pattern p = Pattern.compile("(\\d+:\\d\\d:\\d\\d)\\s*,\\s*(\\d+:\\d\\d:\\d\\d)");
final Matcher m = p.matcher(s);
String result = m.replaceAll("$0|");
Or even
String result = s.replaceAll("?:\\d+:\\d\\d:\\d\\d),\\s*(?:\\d+:\\d\\d:\\d\\d)","$0|");
$0 refers to group 0 which holds entire match.
result is 12:00:00, 2:30:00|3:45:00,23:45:00|
You may consider this replaceAll method using lookarounds:
final String s = "12:00:00, 2:30:003:45:00,23:45:00";
System.out.printf("%s%n", s.replaceAll("(?<=:\\d\\d)(?=(?::\\d{1,2}|$))", "|"));
// 12:00|:00, 2:30|:003:45|:00,23:45|:00|
Lets say I have a string "aabbccaa". Now I want to replace occurrences of "aa" in given string by another string. But it should be in following way.
First occurrence of "aa" should be replaced by "1" and next occurrence of "aa" by "2" and so on.
So, the result of the string becomes "1bbcc2".
You can use replaceFirst() in a for loop where counter is incrementing...
for (int i = 1; string.contains("aa"); i++) {
string = string.replaceFirst("aa", "" + i);
}
You can do it using the Matcher's appendReplacement method:
Pattern p = Pattern.compile("aa");
Matcher m = p.matcher("aabbccaahhhaahhhaaahahhahaaakty");
StringBuffer sb = new StringBuffer();
// Variable "i" serves as a counter. It gets incremented after each replacement.
int i = 0;
while (m.find()) {
m.appendReplacement(sb, ""+(i++));
}
m.appendTail(sb);
System.out.println(sb.toString());
This approach lets you avoid creating multiple string objects (demo).
It is possible to do using Java functions but using a char array and doing it using a lower level of logic would be faster.
String s = "aabbccaa";
String target = "aa";
int i = 1;
String newS;
for (int j = 0; j < s.length; j++) {
newS = s.replaceFirst(target, i++);
j += newS.length - s.length;
s = newS;
}
Here is a solution :
public static void main(String[] a) {
int i = 1;
String before = "aabbccaabbaabbaa";
String regex = "aa";
String after = substitute(i, before, regex);
System.out.println(after);
}
private static String substitute(int i, String before, String regex) {
String after = before.replaceFirst(regex, Integer.toString(i++));
while (!before.equals(after)) {
before = after;
after = before.replaceFirst(regex, Integer.toString(i++));
}
return after;
}
Output :
1bbcc2bb3bb4
I need to change text between tags to upper case in a string and then print the whole string with the changed letters. So
"asdasd <upcase>something</upcase> dfldkflskdf <upcase>stuff</upcase>skdlskd" would become:
"asdasd SOMETHING dfldkflskdf STUFF skdlskd"
So far I got this but it returns the text only from the first ocurrence of the tags.
static String tags (String word)
{
String changed = word;
while (changed.indexOf("<upcase>" ) >= 0)
{
changed = (changed.substring(changed.indexOf("<upcase>")+"<upcase>".length(),changed.indexOf("</upcase>")));
}
return changed.toUpperCase();
First, since you can have more than one string between the upcase tags, you need to return a collection of Strings. I chose a List.
Second, you need to use the String indexOf(string, pos) method, so you don't lose your place in the XML string.
Here's one way to do what you want.
public List<String> tags(String xml) {
List<String> list = new ArrayList<String>();
String startTag = "<upcase>";
String endTag = "</upcase>";
int sPos = xml.indexOf(startTag);
while (sPos >= 0) {
int ePos = xml.indexOf(endTag, sPos + startTag.length());
if (ePos >= 0) {
list.add(xml.substring(sPos + startTag.length(), ePos)
.toUpperCase());
}
sPos = xml.indexOf(startTag, ePos + endTag.length());
}
return list;
}
All right, here is an updated version:
public static String tags(String xml) {
final String upcaseTagRegex = "<upcase>(.*?)</upcase>";
String result = xml;
Pattern pattern = Pattern.compile(upcaseTagRegex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher matcher = pattern.matcher(xml);
while(matcher.find()) {
result = result.replaceFirst(upcaseTagRegex, matcher.group(1).toUpperCase());
}
return result;
}