In Java, I am trying to return all regex matches to an array but it seems that you can only check whether the pattern matches something or not (boolean).
How can I use a regex match to form an array of all string matching a regex expression in a given string?
The period (.) represents the wildcard character. Any character (except for the newline character) will be matched by a period in a regular expression; when you literally want a period in a regular expression you need to precede it with a backslash.
To count a regex pattern multiple times in a given string, use the method len(re. findall(pattern, string)) that returns the number of matching substrings or len([*re. finditer(pattern, text)]) that unpacks all matching substrings into a list and returns the length of it as well.
A regex pattern matches a target string. The pattern is composed of a sequence of atoms. An atom is a single point within the regex pattern which it tries to match to the target string. The simplest atom is a literal, but grouping parts of the pattern to match an atom will require using ( ) as metacharacters.
(4castle's answer is better than the below if you can assume Java >= 9)
You need to create a matcher and use that to iteratively find matches.
import java.util.regex.Matcher; import java.util.regex.Pattern; ... List<String> allMatches = new ArrayList<String>(); Matcher m = Pattern.compile("your regular expression here") .matcher(yourStringHere); while (m.find()) { allMatches.add(m.group()); }
After this, allMatches
contains the matches, and you can use allMatches.toArray(new String[0])
to get an array if you really need one.
You can also use MatchResult
to write helper functions to loop over matches since Matcher.toMatchResult()
returns a snapshot of the current group state.
For example you can write a lazy iterator to let you do
for (MatchResult match : allMatches(pattern, input)) { // Use match, and maybe break without doing the work to find all possible matches. }
by doing something like this:
public static Iterable<MatchResult> allMatches( final Pattern p, final CharSequence input) { return new Iterable<MatchResult>() { public Iterator<MatchResult> iterator() { return new Iterator<MatchResult>() { // Use a matcher internally. final Matcher matcher = p.matcher(input); // Keep a match around that supports any interleaving of hasNext/next calls. MatchResult pending; public boolean hasNext() { // Lazily fill pending, and avoid calling find() multiple times if the // clients call hasNext() repeatedly before sampling via next(). if (pending == null && matcher.find()) { pending = matcher.toMatchResult(); } return pending != null; } public MatchResult next() { // Fill pending if necessary (as when clients call next() without // checking hasNext()), throw if not possible. if (!hasNext()) { throw new NoSuchElementException(); } // Consume pending so next call to hasNext() does a find(). MatchResult next = pending; pending = null; return next; } /** Required to satisfy the interface, but unsupported. */ public void remove() { throw new UnsupportedOperationException(); } }; } }; }
With this,
for (MatchResult match : allMatches(Pattern.compile("[abc]"), "abracadabra")) { System.out.println(match.group() + " at " + match.start()); }
yields
a at 0 b at 1 a at 3 c at 4 a at 5 a at 7 b at 8 a at 10
In Java 9, you can now use Matcher#results()
to get a Stream<MatchResult>
which you can use to get a list/array of matches.
import java.util.regex.Pattern; import java.util.regex.MatchResult;
String[] matches = Pattern.compile("your regex here") .matcher("string to search from here") .results() .map(MatchResult::group) .toArray(String[]::new); // or .collect(Collectors.toList())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With