I have a String:
C6H14
What I want it to be is:
C<sub>6</sub>H<sub>14</sub>
So basically I want to add <sub> before a number and </sub> after a number. How can I accomplish this? Keep in mind that the String can be indefinitely long:
X4Y6Z10W4T12
I'm not a java expert, but I'm pretty sure, you can use regular expressions replace function, where the pattern will be:
(\d+)
and replacement string will be:
<sub>$1</sub>
Sorry I'm not 100% sure about the java syntax, but it can be something like:
str = str.replaceAll("(\\d+)", "<sub>$1</sub>");
This method was added in Java 5
here are some more information about regexp in java:
http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
http://www.regular-expressions.info/java.html
http://javamex.com/tutorials/regular_expressions/search_replace.shtml
I would use a Matcher for that:
StringBuffer sb = new StringBuffer();
Matcher m = Pattern.compile("\\d+").matcher(input);
while(m.find()) {
m.appendReplacement(sb,"<sub>$0</sub>");
}
m.appendTail(sb);
String newString = sb.toString();
You will need to construct a new String object for this - there is no way to change a String "in place" (Strings are immutable)
String.replaceAll will do this for you.
str = str.replaceAll( "\\d+", "<sub>$0</sub>" );
is all you need
java.util.Strings are immutable in Java, so you need to build a new String instance. You have to parse the original string (e.g. using regexes) for that. StringBuilder is a good utility for that.
Use Matcher and Pattern classes with searching for pattern:
"\\d+"
After that, find starting and ending indexes and add <sub> and ''
String are immutable, so we cant insert the sub tags in the existing string. So you would need a method that creates a new string. You could use regex, or use a string builder to generate a new string like this:
public String parseString(String input) {
StringBuilder builder = new StringBuilder();
String format = "<sub>%c</sub>";
for(char c:input.toCharArray()) {
if (Character.isDigit(c)) {
builder.append(String.format(format, c));
} else {
builder.append(c);
}
}
return builder.toString();
}
Related
I have the next String in java:
|ABC|50200|100|50200|200|PRUEBA|ABC|20150220184512|
So I need to replace the value |50200| (second one) with other value according to some decisions,but only need to replace the second one, how can I do, since replace or replaceAll don't work in this case. I was trying with some regex and appendReplacement but it did not work,also I need it to be as quick as possible, code below:
String event = "|ABC|50200|100|50200|200|PRUEBA|ABC|20150220184512|";
Pattern p = Pattern.compile("^\|(\w*)\|(\d+)\|(\d+(\.\d{1,})*)\|(\d+(\.\d{1,})*)\|(\d+(\.\d{1,})*)\|\w+\|\w+\|\d{14}\|$");
Matcher mat = p.matcher(event);
StringBuffer aux = new StringBuffer();
mat.appendReplacement(aux, mat.group(5));
String newString = aux.toString();
But the value of newString is 50200, so basically I want to replace it with 12345, so the String would look like this |ABC|50200|100|12345|200|PRUEBA|ABC|20150220184512|
Thanks in advance for your help
The thing is I have to use the regex to check the format of the String before doing the replace, because there could be other String with different formats
You can use indexOf to find the second position, then substring around the value you want to replace.
For example
public static void main(String[] args) {
String s = "|ABC|50200|100|50200|200|PRUEBA|ABC|20150220184512|";
String find = "50200";
String replace = "12345";
int firstOccur = s.indexOf(find);
int secondOccur = s.indexOf(find, firstOccur+find.length());
StringBuilder sb = new StringBuilder(s.substring(0, secondOccur));
sb.append(replace);
sb.append(s.substring(secondOccur+find.length()));
System.out.println(sb.toString());
// |ABC|50200|100|12345|200|PRUEBA|ABC|20150220184512|
}
Since question has been tagged as regex and non-regex solution is possible but a bit longish here is a simple one line regex solution:
String data = "|ABC|50200|100|50200|200|PRUEBA|ABC|20150220184512|";
String srch = "|50200|";
String repl = "|12345|";
String rdata = data.replaceFirst("^(.*?(\\|50200\\|).*?)\\2", "$1|12345|");
//=> |ABC|50200|100|12345|200|PRUEBA|ABC|20150220184512|
Regex ^(.*?(\|50200\|).*?)\2 finds 2nd instance of |50200| and captures everything before 2nd instance into captured group #1. We use backreference $1 in replacement to put that captured text back.
RegEx Demo
I have a string that has two single quotes in it, the ' character. In between the single quotes is the data I want.
How can I write a regex to extract "the data i want" from the following text?
mydata = "some string with 'the data i want' inside";
Assuming you want the part between single quotes, use this regular expression with a Matcher:
"'(.*?)'"
Example:
String mydata = "some string with 'the data i want' inside";
Pattern pattern = Pattern.compile("'(.*?)'");
Matcher matcher = pattern.matcher(mydata);
if (matcher.find())
{
System.out.println(matcher.group(1));
}
Result:
the data i want
You don't need regex for this.
Add apache commons lang to your project (http://commons.apache.org/proper/commons-lang/), then use:
String dataYouWant = StringUtils.substringBetween(mydata, "'");
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
Pattern pattern = Pattern.compile(".*'([^']*)'.*");
String mydata = "some string with 'the data i want' inside";
Matcher matcher = pattern.matcher(mydata);
if(matcher.matches()) {
System.out.println(matcher.group(1));
}
}
}
There's a simple one-liner for this:
String target = myData.replaceAll("[^']*(?:'(.*?)')?.*", "$1");
By making the matching group optional, this also caters for quotes not being found by returning a blank in that case.
See live demo.
Since Java 9
As of this version, you can use a new method Matcher::results with no args that is able to comfortably return Stream<MatchResult> where MatchResult represents the result of a match operation and offers to read matched groups and more (this class is known since Java 1.5).
String string = "Some string with 'the data I want' inside and 'another data I want'.";
Pattern pattern = Pattern.compile("'(.*?)'");
pattern.matcher(string)
.results() // Stream<MatchResult>
.map(mr -> mr.group(1)) // Stream<String> - the 1st group of each result
.forEach(System.out::println); // print them out (or process in other way...)
The code snippet above results in:
the data I want
another data I want
The biggest advantage is in the ease of usage when one or more results is available compared to the procedural if (matcher.find()) and while (matcher.find()) checks and processing.
Because you also ticked Scala, a solution without regex which easily deals with multiple quoted strings:
val text = "some string with 'the data i want' inside 'and even more data'"
text.split("'").zipWithIndex.filter(_._2 % 2 != 0).map(_._1)
res: Array[java.lang.String] = Array(the data i want, and even more data)
String dataIWant = mydata.replaceFirst(".*'(.*?)'.*", "$1");
as in javascript:
mydata.match(/'([^']+)'/)[1]
the actual regexp is: /'([^']+)'/
if you use the non greedy modifier (as per another post) it's like this:
mydata.match(/'(.*?)'/)[1]
it is cleaner.
String dataIWant = mydata.split("'")[1];
See Live Demo
In Scala,
val ticks = "'([^']*)'".r
ticks findFirstIn mydata match {
case Some(ticks(inside)) => println(inside)
case _ => println("nothing")
}
for (ticks(inside) <- ticks findAllIn mydata) println(inside) // multiple matches
val Some(ticks(inside)) = ticks findFirstIn mydata // may throw exception
val ticks = ".*'([^']*)'.*".r
val ticks(inside) = mydata // safe, shorter, only gets the first set of ticks
Apache Commons Lang provides a host of helper utilities for the java.lang API, most notably String manipulation methods.
In your case, the start and end substrings are the same, so just call the following function.
StringUtils.substringBetween(String str, String tag)
Gets the String that is nested in between two instances of the same
String.
If the start and the end substrings are different then use the following overloaded method.
StringUtils.substringBetween(String str, String open, String close)
Gets the String that is nested in between two Strings.
If you want all instances of the matching substrings, then use,
StringUtils.substringsBetween(String str, String open, String close)
Searches a String for substrings delimited by a start and end tag,
returning all matching substrings in an array.
For the example in question to get all instances of the matching substring
String[] results = StringUtils.substringsBetween(mydata, "'", "'");
you can use this
i use while loop to store all matches substring in the array if you use
if (matcher.find())
{
System.out.println(matcher.group(1));
}
you will get on matches substring so you can use this to get all matches substring
Matcher m = Pattern.compile("[a-zA-Z0-9_.+-]+#[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+").matcher(text);
// Matcher mat = pattern.matcher(text);
ArrayList<String>matchesEmail = new ArrayList<>();
while (m.find()){
String s = m.group();
if(!matchesEmail.contains(s))
matchesEmail.add(s);
}
Log.d(TAG, "emails: "+matchesEmail);
add apache.commons dependency on your pom.xml
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
And below code works.
StringUtils.substringBetween(String mydata, String "'", String "'")
Some how the group(1) didnt work for me. I used group(0) to find the url version.
Pattern urlVersionPattern = Pattern.compile("\\/v[0-9][a-z]{0,1}\\/");
Matcher m = urlVersionPattern.matcher(url);
if (m.find()) {
return StringUtils.substringBetween(m.group(0), "/", "/");
}
return "v0";
I have a String which is formatted as such
[dgdds,dfse][fsefsf,sefs][fsfs,fsef]
How would I use Regex to quickly parse this to return an ArrayList with each value containing one "entry" as such?
ArrayList <String>:
0(String): [dgdds,dfse]
1(String): [fsefsf,sefs]
2(String): [fsfs,fsef]
Really stuck with this, any help would be great.
How about
String myData = "[dgdds,dfse][fsefsf,sefs][fsfs,fsef]";
List<String> list = new ArrayList<>(Arrays.asList(myData
.split("(?<=\\])")));
for (String s : list)
System.out.println(s);
Output:
[dgdds,dfse]
[fsefsf,sefs]
[fsfs,fsef]
This regex will use look behind mechanism to split on each place after ].
You should try this regex :
Pattern pattern = Pattern.compile("\\[\\w*,\\w*\\]");
Old, easy, awesome way :)
String s = "[dgdds,dfse][fsefsf,sefs][fsfs,fsef]";
String[] token = s.split("]");
for (String string : token) {
System.out.println(string + "]");
}
You can use simple \[.*?\] regex, which means: match a string starting with [, later zero or more characters (but as short as possible, not greedly, that's why the ? in .*?), ending with ].
This works, you can test it on Ideone:
List<String> result = new ArrayList<String>();
String input = "[dgdds,dfse][fsefsf,sefs][fsfs,fsef]";
Pattern pattern = Pattern.compile("\\[.*?\\]");
Matcher matcher = pattern.matcher(input);
while (matcher.find())
{
result.add(matcher.group());
}
System.out.println(result);
Output:
[[dgdds,dfse], [fsefsf,sefs], [fsfs,fsef]]
You may need to do it in two passes:
(1) Split out by the brackets if it's just a 1D array (not clear in the question):
String s = "[dgdds,dfse][fsefsf,sefs][fsfs,fsef]";
String[] sArray = s.split("\\[|\\]\\[|\\]");
(2) Split by the commas if you want to also divide, say "dgdds,dfse"
sArray[i].split(",");
We can use split(regex) function directly by escaping "]": "\\]" and then use it as the regex for pattern matching:
String str = "[dgdds,dfse][fsefsf,sefs][fsfs,fsef]";
String bal[] = str.split("\\]");
ArrayList<String>finalList = new ArrayList<>();
for(String s:bal)
{
finalList.add(s+"]");
}
System.out.println(finalList);
Split using this (?:(?<=\])|^)(?=\[) might work if there are nothing between ][
I want to do something like this:
String myString="123EDCBAabcde";
myString=myString.passValidChars("ABCDE");
now myString is "EDCBA"
Is there already a function which only passes the valid characters and removes the others? If not what is the best way to do this?
Best Regards.
myString = myString.replaceAll("[^ABCDE.]+", "");
This is trival to implement.
Start with an empty StringBuilder.
Iterate through each char of myString.
If the char is contained in the String of valid chars, add it to the StringBuilder.
Convert the StringBuilder to a String.
Done.
String string = "123EDCBAabcde";
Pattern pattern = Pattern.compile("[ABCDE]");
Matcher mach = pattern.matcher(string);
StringBuffer str = new StringBuffer();
while(mach.find()){
str.append(mach.group());
}
string = str.toString(); // Now string is "EDCBA"
Guava library (google collections) has the exact class you need: CharMatcher
http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf
Pages 12 up to 19.
Pattern.compile("[^A-Z]").matcher(myString).replaceAll("")
Related to #JB Nizet answer:
static String passValidChar(String in, String validChar){
StringBuilder strBuilder = new StringBuilder();
for(char c : in.toCharArray()){
if(validChar.indexOf(String.valueOf(c)) != -1){
strBuilder.append(c);
}
}
return strBuilder.toString();
}
public static void main(String [] args){
System.out.println(passValidChar("123EDCBAabcde", "EDCBA"));
}
I have been trying to figure out how to extract a portion of a string between two special characters ' and " I've been looking into regex, but frankly I cannot understand it.
Example in Java code:
String str="21*90'89\"";
I would like to pull out 89
In general I would just like to know how to extract part of a string between two specific characters please.
Also it would be nice to know how to extract part of the string from the beginning to a specific character like to get 21.
Try this regular expression:
'(.*?)"
As a Java string literal you will have to write it as follows:
"'(.*?)\""
Here is a more complete example demonstrating how to use this regular expression with a Matcher:
Pattern pattern = Pattern.compile("'(.*?)\"");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
System.out.println(matcher.group(1));
}
See it working online: ideone
If you'll always have a string like that (with 3 parts) then this is enough:
String str= "21*90'89\"";
String between = str.split("\"|'")[1];
Another option, if you can assure that your strings will always be in the format you provide, you can use a quick-and-dirty substring/indexOf solution:
str.substring(str.indexOf("'") + 1, str.indexOf("\""));
And to get the second piece of data you asked for:
str.substring(0, str.indexOf("*"));
public static void main(final String[] args) {
final String str = "21*90'89\"";
final Pattern pattern = Pattern.compile("[\\*'\"]");
final String[] result = pattern.split(str);
System.out.println(Arrays.toString(result));
}
Is what you are looking for... The program described above produces:
[21, 90, 89]
I'm missing the simplest possible solution here:
str.replaceFirst(".*'(.*)\".*", "$1");
This solution is by far the shortest, however it has some drawbacks:
In case the string looks different, you get the whole string back without warning.
It's not very efficient, as the used regex gets compiled for each use.
I wouldn't use it except as a quick hack or if I could be really sure about the input format.
String str="abc#defg#lmn!tp?pqr*tsd";
String special="!?##$%^&*()/<>{}[]:;'`~";
ArrayList<Integer> al=new ArrayList<Integer>();
for(int i=0;i<str.length();i++)
{
for(int j=0;j<special.length();j++)
if(str.charAt(i)==special.charAt(j))
al.add(i);
}
for(int i=0;i<al.size()-1;i++)
{
int start=al.get(i);
int end=al.get(i+1);
for(int j=start+1;j<end;j++)
System.out.print(str.charAt(j));
System.out.print(" ");
}
String str= 21*90'89;
String part= str.split("[*|']");
System.out.println(part[0] +""+part[1]);