match a string with text and store the next text - java

I have a string which contains some text (in Greek language) which was extracted from a pdf.
How can I found a particular text lets say id.name: 123 and then store the number 123?

You can find using a regular expression:
String s = "Έχω ένα string που περιέχει κάποιο κείμενο ( στην ελληνική γλώσσα ), "
+ "το οποίο εξήχθη από ένα PDF .\nΠως μπορώ να ιδρύσω ένα συγκεκριμένο κείμενο "
+ "ας πούμε id.name : 123 και στη συνέχεια να αποθηκεύσετε τον αριθμό 123";
Pattern p = Pattern.compile("id\\.name \\: (\\d+)");
Matcher m = p.matcher(s);
if(m.find()){
System.out.println(m.group(1));
}
Regards.

there are many ways to do it, you can try regular expressions,
for instance let's suppose we have a string call s1 that contain "today is monday" and we can find the word monday, you can do that by:
String matcher = "today is monday";
Pattern p2 = Pattern.compile(".*monday.*");
Matcher m2 = p2.matcher(matcher);
boolean b2 = m2.matches();
if(b2 == true)
{
System.out.println(p2 + " found");
}
else
{
System.out.println(p2 + "no found");
}
}

Related

Get text in the URL with dynamic date - Regex Java

I need to get the text between the URL which has a date in Java
Input 1:
/test1/raw/2019-06-11/testcustomer/usr/pqr/DATA/mn/export/
Output: testcustomer
Only /raw/ remains, date will change and testcustomer will change
Input 2:
/test3/raw/2018-09-01/newcustomer/usr/pqr/DATA/mn/export/
Output: newcustomer
String url = "/test3/raw/2018-09-01/newcustomer/usr/pqr/DATA/mn/export/";
String customer = getCustomer(url);
public String getCustomer (String _url){
String source = "default";
String regex = basePath + "/raw/\\d{4}-\\d{2}-\\d{2}/usr*";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(_url);
if (m.find()) {
source = m.group(1);
} else {
logger.error("Cant get customer with regex " + regex);
}
return source;
}
It's returning 'default' :(
Your regex /raw/\\d{4}-\\d{2}-\\d{2}/usr* is missing the part for the value you want, you need a regex that find the date, and keep what's next :
/\w*/raw/[0-9-]+/(\w+)/.* or (?<=raw\/\d{4}-\d{2}-\d{2}\/)(\w+) will be good
Pattern p = Pattern.compile("/\\w*/raw/[0-9-]+/(\\w+)/.*");
Matcher m = p.matcher(str);
if (m.find()) {
String value = m.group(1);
System.out.println(value);
}
Or if it's always the 4th part, use split()
String value = str.split("/")[4];
System.out.println(value);
And here a >> code demo
Here, we can likely use raw followed by the date as a left boundary, then we would collect our desired output in a capturing group, we would add an slash and consume the rest of our string, with an expression similar to:
.+raw\/[0-9]{4}-[0-9]{2}-[0-9]{2}\/(.+?)\/.+
Demo
Test
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = ".+raw\\/[0-9]{4}-[0-9]{2}-[0-9]{2}\\/(.+?)\\/.+";
final String string = "/test1/raw/2019-06-11/testcustomer/usr/pqr/DATA/mn/export/\n"
+ "/test3/raw/2018-09-01/newcustomer/usr/pqr/DATA/mn/export/";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
RegEx
If this expression wasn't desired or you wish to modify it, please visit regex101.com.
RegEx Circuit
jex.im visualizes regular expressions:

How to recover integers?

I get a string and I have to retrieve the values
Je pense que nous devons utiliser le ".slit"
if (stringReceived.contains("ID")&& stringReceived.contains("Value")) {
here is my character string:
I/RECEIVER: [1/1/0 3
I/RECEIVER: :32:11]
I/RECEIVER: Timestam
I/RECEIVER: p=946697
I/RECEIVER: 531 ID=4
I/RECEIVER: 3 Value=
I/RECEIVER: 18
I receive the value 1 byte by 1 byte.
I would like to recover the value of Timestamp, Id and Value..
You can also use regex for that. Something like:
String example="[11/2/19 9:48:25] Timestamp=1549878505 ID=4 Value=2475";
Pattern pattern=Pattern.compile(".*Timestamp=(\\d+).*ID=(\\d+).*Value=(\\d+)");
Matcher matcher = pattern.matcher(example);
while(matcher.find()) {
System.out.println("Timestamp is:" + matcher.group(1));
System.out.println("Id is:" + matcher.group(2));
System.out.println("Value is:" + matcher.group(3));
}
If the order of tokens can be different (for example ID can come before Timestamp) you can also do it. But since it looks like log which is probably structured I doubt you will need to.
First [11/2/19 9:48:25] seems unnecessary so let's remove it by jumping right into "Timestamp".
Using indexOf(), we can find where Timestamp starts.
// "Timestamp=1549878505 ID=4 Value=2475"
line = line.substring(line.indexOf("Timestamp"));
Since each string is separated by space, we can split it.
// ["Timestamp=1549878505", "ID=4" ,"Value=2475"]
line.split(" ");
Now for each tokens, we can substring it using index of '=' and parse it into string.
for(String token: line.split(" ")) {
int v = Integer.parseInt(token.substring(token.indexOf('=') + 1));
System.out.println(v);
}
Hope that helps :)
String text = "Timestamp=1549878505 ID=4 Value=2475";
Pattern p = Pattern.compile("ID=(\\d)");
Matcher m = p.matcher(text);
if (m.find()) {
System.out.println(m.group(1));
}
output
4
A simple regex is also an option:
private int fromString(String data, String key) {
Pattern pattern = Pattern.compile(key + "=(\\d*)");
Matcher matcher = pattern.matcher(data);
if (matcher.find()) {
return Integer.parseInt(matcher.group(1));
}
return -1;
}
private void test(String data, String key) {
System.out.println(key + " = " + fromString(data, key));
}
private void test() {
String test = "[11/2/19 9:48:25] Timestamp=1549878505 ID=4 Value=2475";
test(test, "Timestamp");
test(test, "ID");
test(test, "Value");
}
prints:
Timestamp = 1549878505
ID = 4
Value = 2475
You can try that:
String txt= "[11/2/19 9:48:25] Timestamp=1549878505 ID=4 Value=2475";
String re1= ".*?\\d+.*?\\d+.*?\\d+.*?\\d+.*?\\d+.*?\\d+.*?(\\d+).*?(\\d+).*?(\\d+)";
Pattern p = Pattern.compile(re1,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m = p.matcher(txt);
if (m.find())
{
String int1=m.group(1);
String int2=m.group(2);
String int3=m.group(3);
System.out.print("("+int1+")"+"("+int2+")"+"("+int3+")"+"\n");
}
Use below code, You will find your timestamp at index 0, id at 1 and value at 2 in List.
Pattern pattern = Pattern.compile("=\\d+");
Matcher matcher = pattern.matcher(stringToMatch);
final List<String> matches = new ArrayList<>();
while (matcher.find()) {
String ans = matcher.group(0);
matches.add(ans.substring(1, ans.length()));
}
Explaining the regex
= matches the character = literally
\d* matches a digit (equal to [0-9])
* Quantifier — Matches between zero and unlimited times, as many times as possible

Find multiple string matches using Java regex

I am trying to use regex to find a match for a string between Si and (P) or Si and (I).
Below is what I wrote. Why isn't it working and how do I fix it?
String Channel = "Si0/4(I) Si0/6( Si0/8K Si0/5(P)";
if (Channel.length() > 0) {
String pattern1 = "Si";
String pattern2 = "(P)";
String pattern3 = "(I)";
String P1 = Pattern.quote(pattern1) + "(.*?)[" + Pattern.quote(pattern2) + "|" + Pattern.quote(pattern3) + "]";
Pattern p = Pattern.compile(P1);
Matcher m = p.matcher(Channel);
while(m.find()){
if (m.group(1)!= null)
{
System.out.println(m.group(1));
}
else if (m.group(2)!= null)
{
System.out.println(m.group(2));
}
}
}
Expected output
0/4
0/5
Actual output
0/4
0/6
0/8K Si0/5
Use a lookbehind and lookahead in your regex. And also you need to add space inside the character class, so that it won't this 0/8K string .
(?<=Si)[^\\( ]*(?=\\((?:P|I)\\))
DEMO
String str="Si0/4(I) Si0/6( Si0/8K Si0/5(P)";
String regex="(?<=Si)[^\\( ]*(?=\\([PI]\\))";
Pattern pattern = Pattern.compile(regex);
Matcher matcher =pattern.matcher(str);
while(matcher.find()){
System.out.println(matcher.group(0));
}
Output:
0/4
0/5
You need to group your regex.It is currently
Si(.*?)[(P)|(I)]
Whereas it should be
Si(.*?)\(I\)|Si(.*?)\(P\)
See demo.
http://regex101.com/r/oO8zI4/8
[] means "any of these character", so it evaluates every letter in the block as if they were separated with OR.
If the result you're searching is always: number/number
You can use:
Si(\d+\/\d+)(?:\(P\)|\(I\))

Regex for floor in address

I have this regex:
String regexPattern = "[0-9A-Za-z]+(st|nd|rd|th)" + " " + "floor";
I want to test it against:
String lineString = "8th floor, Prince's Building, 12 Chater Road";
so I do:
boolean isMatching = lineString.matches(regexPattern);
and it return false. Why?
I thought it had something to do with whitespaces in Java, so I removed the whitespace in the regexPattern variable so it reads
regexPattern = "[0-9A-Za-z]+(st|nd|rd|th)floor";
and matched it with a string without white space:
String lineString = "8thfloor,Prince'sBuilding,12ChaterRoad"
it still returns false. Why? Any help very much appreciated.
String.matches() only returns true if the entire string matches the pattern.
Try adding .* to the beginning and end of your regex.
Example:
String regex = ".*[0-9A-Za-z]+(st|nd|rd|th)" + " " + "floor.*";
This is not the best approach, however...
Here's a better alternative:
String input = "8th floor, Prince's Building, 12 Chater Road";
String regex = "[0-9A-Za-z]+(st|nd|rd|th)" + " " + "floor";
Pattern p = Pattern.compile(regex);
boolean isMatch = p.matcher(input).find();
If you want to extract the floor number, do this:
String input = "8th floor, Prince's Building, 12 Chater Road";
String regex = "([0-9A-Za-z])+(st|nd|rd|th)" + " " + "floor";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
if (m.find()) {
String num = m.group(1);
String suffix = m.group(2);
System.out.println("Welcome to the " + num + suffix + " floor!");
// prints 'Welcome to the 8th floor!'
}
Check out the Pattern API for a boatload of info about Java regular expressions.
Edited, per comments ...
The [0-9A-Za-z]+ part is greedily matching until the end of th.
Try [0-9] instead.

Regex not matching words delimited by whitespace

I have an input string that will follow the pattern /user/<id>?name=<name>, where <id> is alphanumeric but must start with a letter, and <name> is a letter-only string that can have multiple spaces. Some examples of matches would be:
/user/ad?name=a a
/user/one111?name=one ONE oNe
/user/hello?name=world
I came up with the following regex:
String regex = "/user/[a-zA-Z]+\\w*\\?name=[a-zA-Z\\s]+";
All of the above examples match the regex, but it only looks at the first word in <name>. Shouldn't the sequence \s allow me to have white spaces?
The code that I made to test what it is doing is:
String regex = "/user/[a-zA-Z]+\\w*\\?name=[a-zA-Z\\s]+";
// Check to see that input matches pattern
if(Pattern.matches(regex, str) == true){
str = str.replaceFirst("/user/", "");
str = str.replaceFirst("name=", "");
String[] tokens = str.split("\\?");
System.out.println("size = " + tokens.length);
System.out.println("tokens[0] = " + tokens[0]);
System.out.println("tokens[1] = " + tokens[1]);
} else
System.out.println("Didn't match.");
So for example, one test might look like:
/user/myID123?name=firstName LastName
size = 2
tokens[0] = myID123
tokens[1] = firstName
whereas the desired output would be
tokens[1] = firstName LastName
How can I change my regex to do this?
Not sure what you think is the problem in your code. tokens[1] will indeed contain firstName LastName in your example.
Here's an ideone.com demo showing this.
However, have you considered using capturing groups for the id and the name.
If you write it like
String regex = "/user/(\\w+)\\?name=([a-zA-Z\\s]+)";
Matcher m = Pattern.compile(regex).matcher(input);
you can get hold of myID123 and firstName LastName through m.group(1) and m.group(2)
I don't find any fault in your code but you may capture group like this:
String str = "/user/myID123?name=firstName LastName ";
String regex = "/user/([a-zA-Z]+\\w*)\\?name=([a-zA-Z\\s]+)";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
if(m.find()) {
System.out.println(m.group(1) + ", " + m.group(2));
}
The problem is that * is greedy by default (it matches the whole string), so you need to modify your regex by adding a ? (making it reluctant):
List<String> str = Arrays.asList("/user/ad?name=a a", "/user/one111?name=one ONE oNe", "/user/hello?name=world");
String regex = "/user/([a-zA-Z]+\\w*?)\\?name=([a-zA-Z\\s]+)";
for (String s : str) {
Matcher matcher = Pattern.compile(regex).matcher(s);
if (matcher.matches()) {
System.out.println("user: " + matcher.group(1));
System.out.println("name: " + matcher.group(2));
}
}
Output:
user: ad
name: a a
user: one111
name: one ONE oNe
user: hello
name: world

Categories

Resources