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?

Roshanck
quelle
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);
MadProgrammer
quelle
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

Pini Cheyni
quelle
7
Es gibt auch, substringsBetween(...)wenn Sie mehrere Ergebnisse erwarten, was ich gesucht habe. Vielen Dank
Cahen
Link mit mehr Beispiel- commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/…
Avisek Chakraborty
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);
user2656003
quelle
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)); 
Grisha Weintraub
quelle
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
DaoWen
quelle
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);`
Regnerisch
quelle
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
Piotr Chojnacki
quelle
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, "(", ")");
....
ChaitanyaBhatt
quelle
6
String result = s.substring(s.indexOf("(") + 1, s.indexOf(")"));
Techlearner
quelle
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;
}
Yash
quelle
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"
SR
quelle
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);

    }

}
Kumar Vivek Mitra
quelle
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]);
}
Jayy
quelle
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.

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

System.out.println(s.substring(s.indexOf("(")+1,s.indexOf(")")));
Vinod
quelle
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>>
Ravi
quelle
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.

Jonathon Ashworth
quelle
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;
}
Ahmad AlMughrabi
quelle
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");
}
bigiCrab
quelle
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+/
Pascal Tovohery
quelle