Match String with Regex and print in java - java

I am trying to read a JSON feed (it is not JSON parsing) and detect the numbers for further manipulation. This is my trying code:
try {
String regex = "^-?\\d+$";
Pattern myPattern = Pattern.compile(regex);
Matcher regexMatcher = myPattern.matcher(jsonString);
while (regexMatcher.find()) {
for (int i = 0; i < regexMatcher.groupCount(); i++) {
System.out.println(regexMatcher.group(i));
}
}
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}
And this is the JSON string link:
http://uhunt.felix-halim.net/api/cpbook/3
I want to print only the numbers like:
100
-345
785
What is the wrong with my code? I am new in Regex and can't figure out the solution.

For your particular JSON you can use this:
String regex = ", (-?\\d+)";
And regexMatcher.group(1) will give you the number

First, you have to provide "(" and ")" in order to create the matching groups you're looking for.
In addition to that, remove "^" and "$" since there may be more than one hit per line.
This should work:
try {
String regex = "(-?\\d+)";
Pattern myPattern = Pattern.compile(regex);
Matcher regexMatcher = myPattern.matcher(jsonString);
while (regexMatcher.find()) {
for (int i = 0; i < regexMatcher.groupCount(); i++) {
System.out.println(regexMatcher.group(i));
}
}
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}

You can use next regex:
"(?<=, )(-?\\d+)"
or
"(?<=,\\p{Space})(-?\d+)"
In this case regexMatcher.group(0) returns appropriate results.

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

How do I extract substring from this line using RegEx

I have the following String line:
dn: cn=Customer Management,ou=groups,dc=digitalglobe,dc=com
I want to extract just this from the line above: Customer Management
I've tried the following RegEx expression but it does quite do what I want:
^dn: cn=(.*?),
Here is the java code snippet that tests the above expression:
Pattern pattern = Pattern.compile("^dn: cn=(.*?),");
String mydata = "dn: cn=Delivery Admin,ou=groups,dc=digitalglobe,dc=com";
Matcher matcher = pattern.matcher(mydata);
if(matcher.matches()) {
System.out.println(matcher.group(1));
} else {
System.out.println("No match found!");
}
The output is "No match found"... :(
Your regex should work properly, but matches attempts to match the regex to the entire string. Instead, use the find method which will look for a match at any point in the string.
if(matcher.find()) {
System.out.println(matcher.group(1));
} else {
System.out.println("No match found!");
}
Your problem is that the matcher want to match the whole input. Try adding a wildcard to the end of the pattern.
Pattern pattern = Pattern.compile("^dn: cn=(.*?),.*");
String mydata = "dn: cn=Delivery Admin,ou=groups,dc=digitalglobe,dc=com";
Matcher matcher = pattern.matcher(mydata);
if(matcher.matches()) {
System.out.println(matcher.group(1));
} else {
System.out.println("No match found!");
}
Please use below code:
#NOTE: instead of using matches you have to use find
public static void main(String[] args)
{
Pattern pattern = Pattern.compile("^dn: cn=(.*?),");
String mydata = "dn: cn=Delivery Admin,ou=groups,dc=digitalglobe,dc=com";
Matcher matcher = pattern.matcher(mydata);
if(matcher.find()) {
System.out.println(matcher.group(1));
} else {
System.out.println("No match found!");
}
}

Two separate patterns and matchers (java)

I'm working on a simple bot for discord and the first pattern reading works fine and I get the results I'm looking for, but the second one doesn't seem to work and I can't figure out why.
Any help would be appreciated
public void onMessageReceived(MessageReceivedEvent event) {
if (event.getMessage().getContent().startsWith("!")) {
String output, newUrl;
String word, strippedWord;
String url = "http://jisho.org/api/v1/search/words?keyword=";
Pattern reading;
Matcher matcher;
word = event.getMessage().getContent();
strippedWord = word.replace("!", "");
newUrl = url + strippedWord;
//Output contains the raw text from jisho
output = getUrlContents(newUrl);
//Searching through the raw text to pull out the first "reading: "
reading = Pattern.compile("\"reading\":\"(.*?)\"");
matcher = reading.matcher(output);
//Searching through the raw text to pull out the first "english_definitions: "
Pattern def = Pattern.compile("\"english_definitions\":[\"(.*?)]");
Matcher matcher2 = def.matcher(output);
event.getTextChannel().sendMessage(matcher2.toString());
if (matcher.find() && matcher2.find()) {
event.getTextChannel().sendMessage("Reading: "+matcher.group(1)).queue();
event.getTextChannel().sendMessage("Definition: "+matcher2.group(1)).queue();
}
else {
event.getTextChannel().sendMessage("Word not found").queue();
}
}
}
You had to escape the [ character to \\[ (once for the Java String and once for the Regex). You also did forget the closing \".
the correct pattern looks like this:
Pattern def = Pattern.compile("\"english_definitions\":\\[\"(.*?)\"]");
At the output, you might want to readd \" and start/end.
event.getTextChannel().sendMessage("Definition: \""+matcher2.group(1) + "\"").queue();

Regular expression to transform SQL format to java format

I'm trying with no chance to transform sql attributes to java format.
Let's have an example: I want to change: "p_start_date" to "pStartSate".
I've tried to use
String var = "p_start_date";
var.replaceAll("(_[a-z])\1", "([A-Z])\1");
and also
Pattern pattern = Pattern.compile("([a-z0-9]+_)*");
Matcher matcher = pattern.matcher(var);
if (matcher.find()) {
// Get all groups for this match
//System.out.println(matcher.groupCount());
for (int i=0; i<=matcher.groupCount(); i++) {
String groupStr = matcher.group(i);
System.out.println(groupStr);
}
}
But both doesn't work
Is this what you are looking for?
String var = "p_start_date";
Pattern pattern = Pattern.compile("_([a-z])");
Matcher matcher = pattern.matcher(var);
StringBuffer sb=new StringBuffer();
while(matcher.find()) {
matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
}
matcher.appendTail(sb);
System.out.println(sb);
output: pStartDate

Java Regex Replace with Capturing Group

Is there any way to replace a regexp with modified content of capture group?
Example:
Pattern regex = Pattern.compile("(\\d{1,2})");
Matcher regexMatcher = regex.matcher(text);
resultString = regexMatcher.replaceAll("$1"); // *3 ??
And I'd like to replace all occurrence with $1 multiplied by 3.
edit:
Looks like, something's wrong :(
If I use
Pattern regex = Pattern.compile("(\\d{1,2})");
Matcher regexMatcher = regex.matcher("12 54 1 65");
try {
String resultString = regexMatcher.replaceAll(regexMatcher.group(1));
} catch (Exception e) {
e.printStackTrace();
}
It throws an IllegalStateException: No match found
But
Pattern regex = Pattern.compile("(\\d{1,2})");
Matcher regexMatcher = regex.matcher("12 54 1 65");
try {
String resultString = regexMatcher.replaceAll("$1");
} catch (Exception e) {
e.printStackTrace();
}
works fine, but I can't change the $1 :(
edit:
Now, it's working :)
How about:
if (regexMatcher.find()) {
resultString = regexMatcher.replaceAll(
String.valueOf(3 * Integer.parseInt(regexMatcher.group(1))));
}
To get the first match, use #find(). After that, you can use #group(1) to refer to this first match, and replace all matches by the first maches value multiplied by 3.
And in case you want to replace each match with that match's value multiplied by 3:
Pattern p = Pattern.compile("(\\d{1,2})");
Matcher m = p.matcher("12 54 1 65");
StringBuffer s = new StringBuffer();
while (m.find())
m.appendReplacement(s, String.valueOf(3 * Integer.parseInt(m.group(1))));
System.out.println(s.toString());
You may want to look through Matcher's documentation, where this and a lot more stuff is covered in detail.
earl's answer gives you the solution, but I thought I'd add what the problem is that's causing your IllegalStateException. You're calling group(1) without having first called a matching operation (such as find()). This isn't needed if you're just using $1 since the replaceAll() is the matching operation.
Java 9 offers a Matcher.replaceAll() that accepts a replacement function:
resultString = regexMatcher.replaceAll(
m -> String.valueOf(Integer.parseInt(m.group()) * 3));
Source: java-implementation-of-rubys-gsub
Usage:
// Rewrite an ancient unit of length in SI units.
String result = new Rewriter("([0-9]+(\\.[0-9]+)?)[- ]?(inch(es)?)") {
public String replacement() {
float inches = Float.parseFloat(group(1));
return Float.toString(2.54f * inches) + " cm";
}
}.rewrite("a 17 inch display");
System.out.println(result);
// The "Searching and Replacing with Non-Constant Values Using a
// Regular Expression" example from the Java Almanac.
result = new Rewriter("([a-zA-Z]+[0-9]+)") {
public String replacement() {
return group(1).toUpperCase();
}
}.rewrite("ab12 cd efg34");
System.out.println(result);
Implementation (redesigned):
import static java.lang.String.format;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class Rewriter {
private Pattern pattern;
private Matcher matcher;
public Rewriter(String regularExpression) {
this.pattern = Pattern.compile(regularExpression);
}
public String group(int i) {
return matcher.group(i);
}
public abstract String replacement() throws Exception;
public String rewrite(CharSequence original) {
return rewrite(original, new StringBuffer(original.length())).toString();
}
public StringBuffer rewrite(CharSequence original, StringBuffer destination) {
try {
this.matcher = pattern.matcher(original);
while (matcher.find()) {
matcher.appendReplacement(destination, "");
destination.append(replacement());
}
matcher.appendTail(destination);
return destination;
} catch (Exception e) {
throw new RuntimeException("Cannot rewrite " + toString(), e);
}
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(pattern.pattern());
for (int i = 0; i <= matcher.groupCount(); i++)
sb.append(format("\n\t(%s) - %s", i, group(i)));
return sb.toString();
}
}

Categories