Wie bekomme ich eine Zeichenfolge zwischen zwei Zeichen?


89

Ich habe eine Schnur,

String s = "test string (67)";

Ich möchte die Nr. 67 erhalten, die die Zeichenfolge zwischen (und) ist.

Kann mir bitte jemand sagen, wie das geht?


1
Es gibt mehrere Möglichkeiten - Sie die Zeichen im String iterieren, bis Sie das erreichen (oder finden den Index des ersten (und )und tun es mit substring oder, was die meisten Menschen tun würden, einen regulären Ausdruck verwenden.
Andreas Dolk

Antworten:


97

Es gibt wahrscheinlich eine wirklich nette RegExp, aber ich bin kein Neuling in diesem Bereich, also stattdessen ...

String s = "test string (67)";

s = s.substring(s.indexOf("(") + 1);
s = s.substring(0, s.indexOf(")"));

System.out.println(s);

4
Ich denke, dies ist der beste Weg, um die erforderliche Zeichenfolge zu extrahieren, ohne auf die Kuriositäten des Regex-Parsing einzugehen.
Wahrhaftigkeit

3
Regex ist bei weitem mächtiger und kann in mehr Fällen dauern, aber der Einfachheit halber funktioniert dies ...
MadProgrammer

2
Im Ernst, warum sollte dies eine Abwärtsstimme anziehen? Funktioniert es nicht Beantwortet es nicht die ops-Frage?
MadProgrammer

Wenn ich mehrere Werte habe, wie kann ich dann Teilzeichenfolgen verwenden? Wenn ich eine solche Zeichenfolge habe, muss 'this is an example of <how><i have it>'ich Werte zwischen '<' und '>' this
Vignesh

@ Vignesh Verwenden Sie einen regulären Ausdruck
MadProgrammer

71

Eine sehr nützliche Lösung für dieses Problem, die Sie nicht benötigen, um indexOf auszuführen, ist die Verwendung von Apache Commons- Bibliotheken.

 StringUtils.substringBetween(s, "(", ")");

Mit dieser Methode können Sie sogar dann vorgehen, wenn die schließende Zeichenfolge mehrfach vorkommt. Dies ist nicht einfach, wenn Sie nach der schließenden Zeichenfolge indexOf suchen.

Sie können diese Bibliothek hier herunterladen: https://mvnrepository.com/artifact/org.apache.commons/commons-lang3/3.4


7
Es gibt auch, substringsBetween(...)wenn Sie mehrere Ergebnisse erwarten, was ich gesucht habe. Vielen Dank
Cahen


70

Versuchen Sie es so

String s="test string(67)";
String requiredString = s.substring(s.indexOf("(") + 1, s.indexOf(")"));

Die Signatur der Methode für die Teilzeichenfolge lautet:

s.substring(int start, int end);

29

Mit regulären Ausdrücken:

 String s = "test string (67)";
 Pattern p = Pattern.compile("\\(.*?\\)");
 Matcher m = p.matcher(s);
 if(m.find())
    System.out.println(m.group().subSequence(1, m.group().length()-1)); 

2
Ich denke, Sie sollten dies zu einem nicht gierigen Match machen, indem Sie ". *?" stattdessen. Andernfalls wird, wenn die Zeichenfolge so etwas wie "Testzeichenfolge (67) und (68)" ist, "67) und (68" zurückgegeben.
Chthonic Project

17

Java unterstützt reguläre Ausdrücke , aber sie sind etwas umständlich, wenn Sie sie tatsächlich zum Extrahieren von Übereinstimmungen verwenden möchten. Ich denke, der einfachste Weg, um an die in Ihrem Beispiel gewünschte Zeichenfolge zu gelangen, besteht darin, einfach die Unterstützung für reguläre Ausdrücke in der Methode der StringKlasse zu replaceAllverwenden:

String x = "test string (67)".replaceAll(".*\\(|\\).*", "");
// x is now the String "67"

Dies löscht einfach alles bis einschließlich des ersten (und dasselbe für das )und alles danach. Dies lässt nur das Zeug zwischen den Klammern.

Das Ergebnis ist jedoch immer noch ein String. Wenn Sie stattdessen ein ganzzahliges Ergebnis wünschen, müssen Sie eine weitere Konvertierung durchführen:

int n = Integer.parseInt(x);
// n is now the integer 67

9

In einer einzigen Zeile schlage ich vor:

String input = "test string (67)";
input = input.subString(input.indexOf("(")+1, input.lastIndexOf(")"));
System.out.println(input);`

6
String s = "test string (67)";

int start = 0; // '(' position in string
int end = 0; // ')' position in string
for(int i = 0; i < s.length(); i++) { 
    if(s.charAt(i) == '(') // Looking for '(' position in string
       start = i;
    else if(s.charAt(i) == ')') // Looking for ')' position in  string
       end = i;
}
String number = s.substring(start+1, end); // you take value between start and end

6

Sie können dazu die StringUtils der allgemeinen Apache-Bibliothek verwenden.

import org.apache.commons.lang3.StringUtils;
...
String s = "test string (67)";
s = StringUtils.substringBetween(s, "(", ")");
....

6
String result = s.substring(s.indexOf("(") + 1, s.indexOf(")"));

1
Bitte formatieren Sie Ihren Code, indem Sie 4 Leerzeichen einrücken. Außerdem würde ich Ihre Antwort ein wenig .substringausfüllen, indem ich erkläre, was Ihr Code für diejenigen Besucher tut, die sich nicht sicher sind, was und .indexOf` tut.
Bugs

5

Testzeichenfolge, test string (67)aus der Sie die Zeichenfolge abrufen müssen, die zwischen zwei Zeichenfolgen verschachtelt ist.

String str = "test string (67) and (77)", open = "(", close = ")";

Einige mögliche Wege aufgelistet : Einfache generische Lösung:

String subStr = str.substring(str.indexOf( open ) + 1, str.indexOf( close ));
System.out.format("String[%s] Parsed IntValue[%d]\n", subStr, Integer.parseInt( subStr ));

Apache Software Foundation commons.lang3.

StringUtilsDie Klassenfunktion substringBetween()ruft den String ab, der zwischen zwei Strings verschachtelt ist. Es wird nur die erste Übereinstimmung zurückgegeben.

String substringBetween = StringUtils.substringBetween(subStr, open, close);
System.out.println("Commons Lang3 : "+ substringBetween);

Ersetzt die angegebene Zeichenfolge durch die Zeichenfolge, die zwischen zwei Zeichenfolgen verschachtelt ist. #395


Muster mit regulären Ausdrücken: (\()(.*?)(\)).*

Der Punkt passt (fast) zu jedem Zeichen .? = .{0,1}, .* = .{0,}, .+ = .{1,}

String patternMatch = patternMatch(generateRegex(open, close), str);
System.out.println("Regular expression Value : "+ patternMatch);

Regulärer Ausdruck mit der Utility-Klasse RegexUtilsund einigen Funktionen.
      Pattern.DOTALL: Entspricht einem beliebigen Zeichen, einschließlich eines Zeilenabschlusses.
      Pattern.MULTILINE: Entspricht dem gesamten String vom Anfang ^bis zum Ende $der Eingabesequenz.

public static String generateRegex(String open, String close) {
    return "(" + RegexUtils.escapeQuotes(open) + ")(.*?)(" + RegexUtils.escapeQuotes(close) + ").*";
}

public static String patternMatch(String regex, CharSequence string) {
    final Pattern pattern  = Pattern.compile(regex, Pattern.DOTALL);
    final Matcher matcher = pattern .matcher(string);

    String returnGroupValue = null;
    if (matcher.find()) { // while() { Pattern.MULTILINE }
        System.out.println("Full match: " + matcher.group(0));
        System.out.format("Character Index [Start:End]«[%d:%d]\n",matcher.start(),matcher.end());
        for (int i = 1; i <= matcher.groupCount(); i++) {
            System.out.println("Group " + i + ": " + matcher.group(i));
            if( i == 2 ) returnGroupValue = matcher.group( 2 );
        }
    }
    return returnGroupValue;
}

StringUtils ist sehr nützlich
TuGordoBello

4
public String getStringBetweenTwoChars(String input, String startChar, String endChar) {
    try {
        int start = input.indexOf(startChar);
        if (start != -1) {
            int end = input.indexOf(endChar, start + startChar.length());
            if (end != -1) {
                return input.substring(start + startChar.length(), end);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return input; // return null; || return "" ;
}

Verwendung :

String input = "test string (67)";
String startChar = "(";
String endChar   = ")";
String output = getStringBetweenTwoChars(input, startChar, endChar);
System.out.println(output);
// Output: "67"

3

Verwenden Pattern and Matcher

public class Chk {

    public static void main(String[] args) {

        String s = "test string (67)";
        ArrayList<String> arL = new ArrayList<String>();
        ArrayList<String> inL = new ArrayList<String>();

        Pattern pat = Pattern.compile("\\(\\w+\\)");
        Matcher mat = pat.matcher(s);

        while (mat.find()) {

            arL.add(mat.group());
            System.out.println(mat.group());

        }

        for (String sx : arL) {

            Pattern p = Pattern.compile("(\\w+)");
            Matcher m = p.matcher(sx);

            while (m.find()) {

                inL.add(m.group());
                System.out.println(m.group());
            }
        }

        System.out.println(inL);

    }

}

2
Das Sprechen von Variablennamen könnte die Methode benutzerfreundlicher machen.
Zon

2

Eine andere Möglichkeit, die Split-Methode zu verwenden

public static void main(String[] args) {


    String s = "test string (67)";
    String[] ss;
    ss= s.split("\\(");
    ss = ss[1].split("\\)");

    System.out.println(ss[0]);
}

2

Der am wenigsten generische Weg, dies mit Regex- und Pattern / Matcher-Klassen zu tun:

String text = "test string (67)";

String START = "\\(";  // A literal "(" character in regex
String END   = "\\)";  // A literal ")" character in regex

// Captures the word(s) between the above two character(s)
String pattern = START + "(\w+)" + END;

Pattern pattern = Pattern.compile(pattern);
Matcher matcher = pattern.matcher(text);

while(matcher.find()) {
    System.out.println(matcher.group()
        .replace(START, "").replace(END, ""));
}

Dies kann bei komplexeren Regex-Problemen hilfreich sein, bei denen Sie den Text zwischen zwei Zeichensätzen abrufen möchten.


1
String s = "test string (67)";

System.out.println(s.substring(s.indexOf("(")+1,s.indexOf(")")));

1

Die andere mögliche Lösung ist die Verwendung lastIndexOf dort wo von hinten nach Zeichen oder Zeichenfolgen gesucht wird.

In meinem Szenario hatte ich folgendes Stringund ich musste extrahieren<<UserName>>

1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc

Also, indexOfund StringUtils.substringBetweenwar nicht hilfreich, da sie von Anfang an nach Charakter suchen.

Also habe ich benutzt lastIndexOf

String str = "1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc";
String userName = str.substring(str.lastIndexOf("_") + 1, str.lastIndexOf("."));

Und es gibt mir

<<UserName>>

0

Die "generische" Methode besteht darin, die Zeichenfolge von Anfang an zu analysieren, alle Zeichen vor der ersten Klammer wegzuwerfen, die Zeichen nach der ersten Klammer aufzuzeichnen und die Zeichen nach der zweiten Klammer wegzuwerfen.

Ich bin mir sicher, dass es eine Regex-Bibliothek gibt oder etwas, das man tun kann.


Java unterstützt reguläre Ausdrücke. Keine Notwendigkeit für eine regexp4j Bibliothek;)
Andreas Dolk

0

Etwas wie das:

public static String innerSubString(String txt, char prefix, char suffix) {

    if(txt != null && txt.length() > 1) {

        int start = 0, end = 0;
        char token;
        for(int i = 0; i < txt.length(); i++) {
            token = txt.charAt(i);
            if(token == prefix)
                start = i;
            else if(token == suffix)
                end = i;
        }

        if(start + 1 < end)
            return txt.substring(start+1, end);

    }

    return null;
}

0

Es wird die ursprüngliche Zeichenfolge zurückgegeben, wenn kein übereinstimmender regulärer Ausdruck vorliegt

var iAm67 = "test string (67)".replaceFirst("test string \\((.*)\\)", "$1");

Fügen Sie dem Code Übereinstimmungen hinzu

String str = "test string (67)";
String regx = "test string \\((.*)\\)";
if (str.matches(regx)) {
    var iAm67 = str.replaceFirst(regx, "$1");
}

0

Dies ist eine einfache Verwendung von \ D + Regex und job done.
Dadurch werden alle Zeichen außer den Ziffern ausgewählt, ohne dass Komplikationen erforderlich sind

/\D+/
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.