I\'m trying to get the last result of a match without having to cycle through .find()
Here\'s my code:
String in = \"num 123 num 1 num 698 num 19238
Compared to the currently accepted answer, this one does not blindly discard elements of the list using the".*"
prefix. Instead, it uses "(element delimiter)*(element)"
to pick out the last element using .group(2)
. See the function magic_last
in code below.
To demonstrate the benefit of this approach I have also included a function to pick out the n-th element which is robust enough to accept a list that has fewer than n elements. See the function magic
in code below.
Filtering out the "num " text and only getting the number is left as an exercise for the reader (just add an extra group around the digits pattern: ([0-9]+)
and pick out group 4 instead of group 2).
package com.example;
import static java.lang.System.out;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Foo {
public static void main (String [] args) {
String element = "num [0-9]+";
String delimiter = ", ";
String input;
input = "here is a num bro: num 001; hope you like it";
magic_last(input, element, delimiter);
magic(1, input, element, delimiter);
magic(2, input, element, delimiter);
magic(3, input, element, delimiter);
input = "here are some nums bro: num 001, num 002, num 003, num 004, num 005, num 006; hope you like them";
magic_last(input, element, delimiter);
magic(1, input, element, delimiter);
magic(2, input, element, delimiter);
magic(3, input, element, delimiter);
magic(4, input, element, delimiter);
magic(5, input, element, delimiter);
magic(6, input, element, delimiter);
magic(7, input, element, delimiter);
magic(8, input, element, delimiter);
}
public static void magic_last (String input, String element, String delimiter) {
String regexp = "(" + element + delimiter + ")*(" + element + ")";
Pattern pattern = Pattern.compile(regexp);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
out.println(matcher.group(2));
}
}
public static void magic (int n, String input, String element, String delimiter) {
String regexp = "(" + element + delimiter + "){0," + (n - 1) + "}(" + element + ")(" + delimiter + element + ")*";
Pattern pattern = Pattern.compile(regexp);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
out.println(matcher.group(2));
}
}
}
Output:
num 001
num 001
num 001
num 001
num 006
num 001
num 002
num 003
num 004
num 005
num 006
num 006
num 006
String in = "num 123 num 1 num 698 num 19238 num 2134";
Pattern p = Pattern.compile("num '([0-9]+) ");
Matcher m = p.matcher(in);
String result = "";
while (m.find())
{
result = m.group(1);
}
Java patterns are greedy by default, the following should do it.
String in = "num 123 num 1 num 698 num 19238 num 2134";
Pattern p = Pattern.compile( ".*num ([0-9]+).*$" );
Matcher m = p.matcher( in );
if ( m.matches() )
{
System.out.println( m.group( 1 ));
}
Use negative lookahead:
String in = "num 123 num 1 num 698 num 19238 num 2134";
Pattern p = Pattern.compile("num (\\d+)(?!.*num \\d+)");
Matcher m = p.matcher(in);
if (m.find()) {
in= m.group(1);
}
The regular expression reads as "num followed by one space and at least one digit without any (num followed by one space and at least one digit) at any point after it".
You can get even fancier by combining it with positive lookbehind:
String in = "num 123 num 1 num 698 num 19238 num 2134";
Pattern p = Pattern.compile("(?<=num )\\d+(?!.*num \\d+)");
Matcher m = p.matcher(in);
if (m.find()) {
in = m.group();
}
That one reads as "at least one digit preceded by (num and one space) and not followed by (num followed by one space and at least one digit) at any point after it".
That way you don't have to mess with grouping and worry about the potential IndexOutOfBoundsException
thrown from Matcher.group(int)
.
just use \Z - end of string mach
String in = "num 123 num 1 num 698 num 19238 num 2134";
Pattern p = Pattern.compile("num ([0-9]+)\\Z");
Matcher m = p.matcher(in);
if (m.find()) {
in = m.group(1);
}
Regular expressions are greedy:
Matcher m=Pattern.compile(".*num '([0-9]+) ",Pattern.DOTALL).matcher("num 123 num 1 num 698 num 19238 num 2134");
will give you a Matcher
for the last match, and you can apply it to most regexes by prepending ".*". Of course, if you can't use DOTALL
, you might want to use (?:\d|\D)
or something similar as your wildcard.