Extracting Number from URL in Java via Regex - java

Take URL http://www.abc.com/alpha/beta/33445566778899/gamma/delta
i need to return the number 33445566778899 (with forward slashes removed, number is of variable length but between 10 & 20 digits)
Simple enough (or so i thought) except everything I've tried doesn't seem to work but why?
Pattern pattern = Pattern.compile("\\/([0-9])\\d{10,20}\\/");
Matcher matcher = pattern.matcher(fullUrl);
if (matcher.find()) {
return matcher.group(1);
}

Try this one-liner:
String number = url.replaceAll(".*/(\\d{10,20})/.*", "$1");

This regex works -
"\\/(\\d{10,20})\\/"
Testing it-
String fullUrl = "http://www.abc.com/alpha/beta/33445566778899/gamma/delta";
Pattern pattern = Pattern.compile("\\/(\\d{10,20})\\/");
Matcher matcher = pattern.matcher(fullUrl);
if (matcher.find()) {
System.out.println(matcher.group(1));
}
OUTPUT - 33445566778899

Try,
String url = "http://www.abc.com/alpha/beta/33445566778899/gamma/delta";
String digitStr = null;
for(String str : url.split("/")){
System.out.println(str);
if(str.matches("[0-9]{10,20}")){
digitStr = str;
break;
}
}
System.out.println(digitStr);
Output:
33445566778899

Instead of saying it "doesn't seem to work", you should have given use what it was returning. Testing it confirmed what I thought: your code would return 3 for this input.
This is simply because your regexp as written will capture a digit following a / and followed by 10 to 20 digits themselves followed by a /.
The regex you want is "/(\\d{10,20})/" (you don't need to escape the /). Below you'll find the code I tested this with.
public static void main(String[] args) {
String src = "http://www.abc.com/alpha/beta/33445566778899/gamma/delta";
Pattern pattern = Pattern.compile("/(\\d{10,20})/");
Matcher matcher = pattern.matcher(src);
if (matcher.find()) {
System.out.println(matcher.group(1));
}
}

Related

Regex to split the first from a "/token1/token2/token3"

I'm pretty rusty with regex, but I have the requirement to extract the first token of the following string:
Input: /token1/token2/token3
Required output: /token1
I have tried:
List<String> connectorPath = Splitter.on("^[/\\w+]+")
.trimResults()
.splitToList(actionPath);
Doesn't work for me, any ideas?
Instead of split, you can match
^/\\w+
Or if the string has 3 parts, use a capture group for the first part.
^(/\\w+)/\\w+/\\w+$
Java example
Pattern pattern = Pattern.compile("^/\\w+");
Matcher matcher = pattern.matcher("/token1/token2/token3");
if (matcher.find()) {
System.out.println(matcher.group(0));
}
Output
/token1
You can split on the / that is not at the string start using the (?!^)/ regex:
String[] res = "/token1/token2/token3".split("(?!^)/");
System.out.println(res[0]); // => /token1
See the Java code demo and the regex demo.
(?!^) - a negative lookahead that matches a location not at the start of string
/ - a / char.
Using Guava:
Splitter splitter = Splitter.onPattern("(?!^)/").trimResults();
Iterable<String> iterable = splitter.split(actionPath);
String first = Iterables.getFirst(iterable, "");
You are over-complicating it.
Try the following regular expression: ^(\/\w+)(.+)$
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PathSplitter {
public static void main(String args[]) {
String input = "/token1/token2/token3";
Pattern pattern = Pattern.compile("^(\\/\\w+)(.+)$");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println(matcher.group(1)); // /token1
System.out.println(matcher.group(2)); // /token2/token3
} else {
System.out.println("NO MATCH");
}
}
}

Java regex does not match as expected

I'm starting with regex in Java recently, and I cant wrap my head around this problem.
Pattern p = Pattern.compile("[^A-Z]+");
Matcher matcher = p.matcher("GETs");
if (matcher.matches()) {
System.out.println("Matched.");
} else {
System.out.println("Did not match.");
}
Result: Did not Match(Unexpected result) Explain this
I get the output "Did not match." This is strange to me, while reading https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html,
I'm using the X+, which matches "One, or more times".
I thought my code in words would go something like this:
"Check if there is one or more characters in the string "GETs" which does not belong in A to Z."
So I'm expecting the following result:
"Yes, there is one character that does not belong to A-Z in "GETs", the regex was a match."
However this is not the case, I'm confused to why this is.
I tried the following:
Pattern p = Pattern.compile("[A-Z]+");
Matcher matcher = p.matcher("GETs");
if (matcher.matches()) {
System.out.println("Matched.");
} else {
System.out.println("Did not match.");
}
Result: Did not match. (Expected result)
Pattern p = Pattern.compile("[A-Z]+");
Matcher matcher = p.matcher("GET");
if (matcher.matches()) {
System.out.println("Matched.");
} else {
System.out.println("Did not match.");
}
Result: Matched. (Expected result)
Please, explain why my first example did not work.
Matcher.matches returns true only if the ENTIRE region
matches the pattern.
For the output you are looking for, use Matches.find instead
Explanation of each case:
Pattern p = Pattern.compile("[^A-Z]+");
Matcher matcher = p.matcher("GETs");
if (matcher.matches()) {
Fails because the ENTIRE region 'GETs' isn't lowercase
Pattern p = Pattern.compile("[A-Z]+");
Matcher matcher = p.matcher("GETs");
if (matcher.matches()) {
This fails because the ENTIRE region 'GETs' isn't uppercase
Pattern p = Pattern.compile("[A-Z]+");
Matcher matcher = p.matcher("GET");
if (matcher.matches()) {
The ENTIRE region 'GET' is uppercase, the pattern matches.
You're very first regex asks to match any character that is not in an uppercase range of A-Z. The match is on the lowercase "s" in GETs.
if you want a regex to match either in UPPERCASE and lowercase, you can use this:
String test = "yes";
String test2= "YEs";
test.matches("(?i).*\\byes\\b.*");
test2.matches("(?i).*\\byes\\b.*");
will return true in the two cases

Creating regex to extract 4 digit number from string using java

Hi I am trying to build one regex to extract 4 digit number from given string using java. I tried it in following ways:
String mydata = "get the 0025 data from string";
Pattern pattern = Pattern.compile("^[0-9]+$");
//Pattern pattern = Pattern.compile("^[0-90-90-90-9]+$");
//Pattern pattern = Pattern.compile("^[\\d]+$");
//Pattern pattern = Pattern.compile("^[\\d\\d\\d\\d]+$");
Matcher matcher = pattern.matcher(mydata);
String val = "";
if (matcher.find()) {
System.out.println(matcher.group(1));
val = matcher.group(1);
}
But it's not working properly. How to do this. Need some help. Thank you.
Change you pattern to:
Pattern pattern = Pattern.compile("(\\d{4})");
\d is for a digit and the number in {} is the number of digits you want to have.
If you want to end up with 0025,
String mydata = "get the 0025 data from string";
mydata = mydata.replaceAll("\\D", ""); // Replace all non-digits
Pattern pattern = Pattern.compile("\\b[0-9]+\\b");
This should do it for you.^$ will compare with the whole string.It will match string with only numbers.
Remove the anchors.. put paranthesis if you want them in group 1:
Pattern pattern = Pattern.compile("([0-9]+)"); //"[0-9]{4}" for 4 digit number
And extract out matcher.group(1)
Many better answers, but if you still have to use in the same way.
String mydata = "get the 0025 data from string";
Pattern pattern = Pattern.compile("(?<![-.])\\b[0-9]+\\b(?!\\.[0-9])");
Matcher matcher = pattern.matcher(mydata);
String val = "";
if (matcher.find()) {
System.out.println(matcher.group(0));
val = matcher.group(0);
}
changed matcher.group(1); to matcher.group(0);
You can go with \d{4} or [0-9]{4} but note that by specifying the ^ at the beginning of regex and $ at the end you're limiting yourself to strings that contain only 4 digits.
My recomendation: Learn some regex basics.
Scanner sc=new Scanner(System.in);
HashMap<String,String> a=new HashMap<>();
ArrayList<String> b=new ArrayList<>();
String s=sc.nextLine();
Pattern p=Pattern.compile("\\d{4}");
Matcher m=p.matcher(s);
while(m.find())
{
String x="";
x=x+(m.group(0));
a.put(x,"0");
b.add(x);
}
System.out.println(a.size());
System.out.println(b);
You can find all matched digit patterns and unique patterns (for unique use Set<String> k=b.keySet();)
If you want to match any number of digits then use pattern like the following:
^\D*(\d+)\D*$
And for exactly 4 digits go for
^\D*(\d{4})\D*$

Regex after a special character in Java

I am using regex in java to get a specific output from a list of rooms at my University.
A outtake from the list looks like this:
(A55:G260) Laboratorium 260
(A55:G292) Grupperom 292
(A55:G316) Grupperom 316
(A55:G366) Grupperom 366
(HDS:FLØYEN) Fløyen (appendix)
(ODO:PC-STUE) Pulpakammeret (PC-stue)
(SALEM:KONF) Konferanserom
I want to get the value that comes between the colon and the parenthesis.
The regex I am using at the moment is:
pattern = Pattern.compile("[:]([A-Za-z0-9ÆØÅæøå-]+)");
matcher = pattern.matcher(room.text());
I've included ÆØÅ, because some of the rooms have Norwegian letters in them.
Unfortunately the regex includes the building code also (e.g. "A55") in the output... Comes out like this:
A55
A55
A55
:G260
:G292
:G316
Any ideas on how to solve this?
The problem is not your regular expression. You need to reference group(1) for the match result.
while (matcher.find()) {
System.out.println(matcher.group(1));
}
However, you may consider using a negated character class instead.
pattern = Pattern.compile(":([^)]+)");
You can try a regex like this :
public static void main(String[] args) {
String s = "(HDS:FLØYEN) Fløyen (appendix)";
// select everything after ":" upto the first ")" and replace the entire regex with the selcted data
System.out.println(s.replaceAll(".*?:(.*?)\\).*", "$1"));
String s1 = "ODO:PC-STUE) Pulpakammeret (PC-stue)";
System.out.println(s1.replaceAll(".*?:(.*?)\\).*", "$1"));
}
O/P :
FLØYEN
PC-STUE
Can try with String Opreations as follows,
String val = "(HDS:FLØYEN) Fløyen (appendix)";
if(val.contains(":")){
String valSub = val.split("\\s")[0];
System.out.println(valSub);
valSub = valSub.substring(1, valSub.length()-1);
String valA = valSub.split(":")[0];
String valB = valSub.split(":")[1];
System.out.println(valA);
System.out.println(valB);
}
Output :
(HDS:FLØYEN)
HDS
FLØYEN
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class test
{
public static void main( String args[] ){
// String to be scanned to find the pattern.
String line = "(HDS:FLØYEN) Fløyen (appendix)";
String pattern = ":([^)]+)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
while (m.find()) {
System.out.println(m.group(1));
}
}
}

Splitting a string composed of numbers and alphabets

I want to break a string like :
String s = "xyz213123kop234430099kpf4532";
into tokens where each token starts with an alphabet and ends with a number. So the above string can be broken down into 3 tokens :
xyz213123
kop234430099
kpf4532
This string s could be very big but the pattern will remain the same, i.e each token will start with 3 alphabets and end with a number.
How do I split them ?
Try this:
\w+?\d+
Java Matcher:
Pattern pattern = Pattern.compile("\\w+?\\d+"); //compiles the pattern we want to use
Matcher matcher = pattern.matcher("xyz213123kop234430099kpf4532"); //we create the matcher on certain string using our pattern
while(matcher.find()) //while the matcher can find the next match
{
System.out.println(matcher.group()); //print it
}
And then you could use Regex.Matches C#:
foreach(Match m in Regex.Matches("xyz213123kop234430099kpf4532", #"\w+?\d+"))
{
Console.WriteLine(m.Value);
}
And for the future this:
RegExr
Do it like this,
String s = "xyz213123kop234430099kpf4532";
Pattern p = Pattern.compile("\\w+?\\d+");
Matcher match = p.matcher(s);
while(match.find()){
System.out.println(match.group());
}
OUTPUT
xyz213123
kop234430099
kpf4532
You can start from such regexp: (\w+?\d+)
http://regexr.com?36utt

Categories

Resources