it-swarm.com.de

Erstellen Sie eine Reihe von Regex-Übereinstimmungen

In Java versuche ich, alle Regex-Übereinstimmungen an ein Array zurückzugeben, aber es scheint, dass Sie nur überprüfen können, ob das Muster mit etwas übereinstimmt oder nicht (Boolescher Wert).

Wie kann ich eine Regex-Übereinstimmung verwenden, um ein Array aller Zeichenfolgen zu bilden, die einem Regex-Ausdruck in einer bestimmten Zeichenfolge entsprechen?

138
Jake Sankey

( 4castle's answer ist besser als das Folgende, wenn Sie davon ausgehen können, dass Java> = 9)

Sie müssen einen Matcher erstellen und diesen verwenden, um iterativ Übereinstimmungen zu finden.

 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());
 }

Danach enthält allMatches die Übereinstimmungen, und Sie können allMatches.toArray(new String[0]) verwenden, um ein Array abzurufen, wenn Sie wirklich eines benötigen.


Sie können auch MatchResult verwenden, um Hilfsfunktionen zu schreiben, mit denen Übereinstimmungen durchlaufen werden, da Matcher.toMatchResult() eine Momentaufnahme des aktuellen Gruppenstatus zurückgibt.

Sie können zum Beispiel einen faulen Iterator schreiben, der dies zulässt

for (MatchResult match : allMatches(pattern, input)) {
  // Use match, and maybe break without doing the work to find all possible matches.
}

indem du so etwas machst:

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(); }
      };
    }
  };
}

Mit diesem,

for (MatchResult match : allMatches(Pattern.compile("[abc]"), "abracadabra")) {
  System.out.println(match.group() + " at " + match.start());
}

ausbeuten

a at 0
b at 1
a at 3
c at 4
a at 5
a at 7
b at 8
a at 10
246
Mike Samuel

In Java 9 können Sie jetzt Matcher#results() verwenden, um Stream<MatchResult> mit dem Sie eine Liste/ein Array von Übereinstimmungen abrufen können.

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())
33
4castle

Java macht Regex zu kompliziert und folgt nicht dem Perl-Stil. Schauen Sie sich MentaRegex an, um zu sehen, wie Sie dies in einer einzelnen Zeile von Java code:

String[] matches = match("aa11bb22", "/(\\d+)/g" ); // => ["11", "22"]
25

Hier ist ein einfaches Beispiel:

Pattern pattern = Pattern.compile(regexPattern);
List<String> list = new ArrayList<String>();
Matcher m = pattern.matcher(input);
while (m.find()) {
    list.add(m.group());
}

(Wenn Sie über mehr Erfassungsgruppen verfügen, können Sie diese durch ihren Index als Argument der Gruppenmethode referenzieren. Wenn Sie ein Array benötigen, verwenden Sie list.toArray())

8
Bozho

Aus dem Official Regex Java Trails :

        Pattern pattern = 
        Pattern.compile(console.readLine("%nEnter your regex: "));

        Matcher matcher = 
        pattern.matcher(console.readLine("Enter input string to search: "));

        boolean found = false;
        while (matcher.find()) {
            console.format("I found the text \"%s\" starting at " +
               "index %d and ending at index %d.%n",
                matcher.group(), matcher.start(), matcher.end());
            found = true;
        }

Verwenden Sie find und fügen Sie das resultierende group in Ihr Array/List/whatever ein.

5
Anthony Accioly
        Set<String> keyList = new HashSet();
        Pattern regex = Pattern.compile("#\\{(.*?)\\}");
        Matcher matcher = regex.matcher("Content goes here");
        while(matcher.find()) {
            keyList.add(matcher.group(1)); 
        }
        return keyList;
0
Nikhil Kumar K