webentwicklung-frage-antwort-db.com.de

Verwenden von regulären Ausdrücken zum Extrahieren eines Werts in Java

Ich habe mehrere Strings in der groben Form:

[some text] [some number] [some more text]

Ich möchte den Text in [Nummer] mit den Java-Regex-Klassen extrahieren.

Ich weiß ungefähr, welchen regulären Ausdruck ich verwenden möchte (obwohl alle Vorschläge willkommen sind). Was mich wirklich interessiert, sind die Java-Aufrufe, die den Regex-String verwenden und ihn in den Quelldaten verwenden, um den Wert [einige Anzahl] zu erzeugen.

EDIT: Ich sollte hinzufügen, dass mich nur eine einzige Zahl interessiert (im Grunde die erste Instanz). Die Quellstrings sind kurz und ich werde nicht nach mehreren Vorkommen von [einigen Zahlen] suchen.

145
Craig Walker

Vollständiges Beispiel:

private static final Pattern p = Pattern.compile("^([a-zA-Z]+)([0-9]+)(.*)");
public static void main(String[] args) {
    // create matcher for pattern p and given string
    Matcher m = p.matcher("Testing123Testing");

    // if an occurrence if a pattern was found in a given string...
    if (m.find()) {
        // ...then you can use group() methods.
        System.out.println(m.group(0)); // whole matched expression
        System.out.println(m.group(1)); // first expression from round brackets (Testing)
        System.out.println(m.group(2)); // second one (123)
        System.out.println(m.group(3)); // third one (Testing)
    }
}

Da Sie nach der ersten Nummer suchen, können Sie einen solchen Regex verwenden:

^\D+(\d+).*

und m.group(1) wird Ihnen die erste Nummer zurückgeben. Beachten Sie, dass signierte Zahlen ein Minuszeichen enthalten können:

^\D+(-?\d+).*
283
Allain Lalonde
import Java.util.regex.Matcher;
import Java.util.regex.Pattern;

public class Regex1 {
    public static void main(String[]args) {
        Pattern p = Pattern.compile("\\d+");
        Matcher m = p.matcher("hello1234goodboy789very2345");
        while(m.find()) {
            System.out.println(m.group());
        }
    }
}

Ausgabe:

1234
789
2345
34
javaMan

Allain hat im Wesentlichen den Java-Code, sodass Sie diesen verwenden können. Sein Ausdruck stimmt jedoch nur mit if vor Ihren Zahlen ist nur ein Stream von Word-Zeichen vorangestellt. 

"(\\d+)"

sollte in der Lage sein, die erste Ziffernfolge zu finden. Sie müssen nicht das Vorhergehende angeben, wenn Sie sicher sind, dass es sich um die erste Ziffernfolge handelt. Ebenso ist es nicht sinnvoll anzugeben, was danach ist, es sei denn, Sie möchten dies. Wenn Sie nur die Nummer haben möchten und sicher sind, dass es sich um die erste Zeichenfolge einer oder mehrerer Ziffern handelt, brauchen Sie nichts weiter. 

Wenn Sie davon ausgehen, dass es durch Leerzeichen versetzt wird, wird die Angabe noch deutlicher 

"\\s+(\\d+)\\s+"

könnte besser sein 

Wenn Sie alle drei Teile benötigen, müssen Sie Folgendes tun:

"(\\D+)(\\d+)(.*)"

EDITDie von Allain und Jack gegebenen Ausdrücke legen nahe, dass Sie eine Teilmenge von Nicht-Ziffern angeben müssen, um Ziffern erfassen zu können. Wenn Sie der Regex-Engine mitteilen, dass Sie nach \d suchen, wird alles vor den Ziffern ignoriert. Wenn der Ausdruck von J oder A passt zu Ihrem Muster passt, dann ist das gesamte Match gleich die Eingabezeichenfolge. Und es gibt keinen Grund, es anzugeben. Es wird wahrscheinlich ein sauberes Match verlangsamt, wenn es nicht völlig ignoriert wird. 

33
Axeman

Neben Pattern verfügt die Java String - Klasse auch über mehrere Methoden, die mit regulären Ausdrücken arbeiten können.

"ab123abc".replaceFirst("\\D*(\\d*).*", "$1")

dabei ist \\D ein nicht-stelliges Zeichen.

11

In Java 1.4 und höher:

String input = "...";
Matcher matcher = Pattern.compile("[^0-9]+([0-9]+)[^0-9]+").matcher(input);
if (matcher.find()) {
    String someNumberStr = matcher.group(1);
    // if you need this to be an int:
    int someNumberInt = Integer.parseInt(someNumberStr);
}
9
Jack Leow

Diese Funktion sammelt alle passenden Sequenzen aus string. In diesem Beispiel werden alle E-Mail-Adressen von String übernommen.

static final String EMAIL_PATTERN = "[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
        + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})";

public List<String> getAllEmails(String message) {      
    List<String> result = null;
    Matcher matcher = Pattern.compile(EMAIL_PATTERN).matcher(message);

    if (matcher.find()) {
        result = new ArrayList<String>();
        result.add(matcher.group());

        while (matcher.find()) {
            result.add(matcher.group());
        }
    }

    return result;
}

Für message = "[email protected], <[email protected]>>>> [email protected]" wird eine Liste mit 3 Elementen erstellt.

6
LukaszTaraszka

Versuchen Sie so etwas zu tun:

Pattern p = Pattern.compile("^.+(\\d+).+");
Matcher m = p.matcher("Testing123Testing");

if (m.find()) {
    System.out.println(m.group(1));
}
3
Tint Naing Win

Einfache Lösung

// Regexplanation:
// ^       beginning of line
// \\D+    1+ non-digit characters
// (\\d+)  1+ digit characters in a capture group
// .*      0+ any character
String regexStr = "^\\D+(\\d+).*";

// Compile the regex String into a Pattern
Pattern p = Pattern.compile(regexStr);

// Create a matcher with the input String
Matcher m = p.matcher(inputStr);

// If we find a match
if (m.find()) {
    // Get the String from the first capture group
    String someDigits = m.group(1);
    // ...do something with someDigits
}

Lösung in einer Util-Klasse

public class MyUtil {
    private static Pattern pattern = Pattern.compile("^\\D+(\\d+).*");
    private static Matcher matcher = pattern.matcher("");

    // Assumptions: inputStr is a non-null String
    public static String extractFirstNumber(String inputStr){
        // Reset the matcher with a new input String
        matcher.reset(inputStr);

        // Check if there's a match
        if(matcher.find()){
            // Return the number (in the first capture group)
            return matcher.group(1);
        }else{
            // Return some default value, if there is no match
            return null;
        }
    }
}

...

// Use the util function and print out the result
String firstNum = MyUtil.extractFirstNumber("Testing4234Things");
System.out.println(firstNum);
2
NoBrainer

Sie können es mit StringTokenizer .__ tun.

String str = "as:"+123+"as:"+234+"as:"+345;
StringTokenizer st = new StringTokenizer(str,"as:");

while(st.hasMoreTokens())
{
  String k = st.nextToken();    // you will get first numeric data i.e 123
  int kk = Integer.parseInt(k);
  System.out.println("k string token in integer        " + kk);

  String k1 = st.nextToken();   //  you will get second numeric data i.e 234
  int kk1 = Integer.parseInt(k1);
  System.out.println("new string k1 token in integer   :" + kk1);

  String k2 = st.nextToken();   //  you will get third numeric data i.e 345
  int kk2 = Integer.parseInt(k2);
  System.out.println("k2 string token is in integer   : " + kk2);
}

Da wir diese numerischen Daten in drei verschiedene Variablen einbinden, können wir sie an beliebiger Stelle im Code verwenden (zur weiteren Verwendung).

1
shounak

Wie wäre es mit [^\\d]*([0-9]+[\\s]*[.,]{0,1}[\\s]*[0-9]*).* Ich denke, es würde sich um Zahlen mit Bruchteil kümmern. Ich habe Leerzeichen und , als mögliches Trennzeichen eingefügt. Ich versuche, die Zahlen aus einer Zeichenfolge einschließlich Floats herauszuholen und zu berücksichtigen, dass der Benutzer möglicherweise einen Fehler macht und beim Eingeben der Nummer Leerzeichen enthält .

0
arturo

Manchmal können Sie die einfache .split ("REGEXP") -Methode verwenden, die in Java.lang.String verfügbar ist. Zum Beispiel:

String input = "first,second,third";

//To retrieve 'first' 
input.split(",")[0] 
//second
input.split(",")[1]
//third
input.split(",")[2]
0
user1722707
Pattern p = Pattern.compile("(\\D+)(\\d+)(.*)");
Matcher m = p.matcher("this is your number:1234 thank you");
if (m.find()) {
    String someNumberStr = m.group(2);
    int someNumberInt = Integer.parseInt(someNumberStr);
}
0
User User