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);
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.
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));
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
String s ="test string (67)";int start =0;// '(' position in stringint end =0;// ')' position in stringfor(int i =0; i < s.length(); i++){if(s.charAt(i)=='(')// Looking for '(' position in string
start = i;elseif(s.charAt(i)==')')// Looking for ')' position in string
end = i;}String number = s.substring(start+1, end);// you take value between start and end
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 ));
StringUtilsDie Klassenfunktion substringBetween()ruft den String ab, der zwischen zwei Strings verschachtelt ist. Es wird nur die erste Übereinstimmung zurückgegeben.
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.
publicstaticString generateRegex(String open,String close){return"("+RegexUtils.escapeQuotes(open)+")(.*?)("+RegexUtils.escapeQuotes(close)+").*";}publicstaticString patternMatch(String regex,CharSequence string){finalPattern pattern =Pattern.compile(regex,Pattern.DOTALL);finalMatcher 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;}
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 regexString 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.
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.
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
(
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.Antworten:
Es gibt wahrscheinlich eine wirklich nette RegExp, aber ich bin kein Neuling in diesem Bereich, also stattdessen ...
quelle
'this is an example of <how><i have it>'
ich Werte zwischen '<' und '>' thisEine 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.
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
quelle
substringsBetween(...)
wenn Sie mehrere Ergebnisse erwarten, was ich gesucht habe. Vielen DankVersuchen Sie es so
Die Signatur der Methode für die Teilzeichenfolge lautet:
quelle
Mit regulären Ausdrücken:
quelle
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
String
Klasse zureplaceAll
verwenden: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:quelle
In einer einzigen Zeile schlage ich vor:
quelle
quelle
Sie können dazu die StringUtils der allgemeinen Apache-Bibliothek verwenden.
quelle
quelle
.substring
ausfüllen, indem ich erkläre, was Ihr Code für diejenigen Besucher tut, die sich nicht sicher sind, was und .indexOf` tut.Testzeichenfolge,
test string (67)
aus der Sie die Zeichenfolge abrufen müssen, die zwischen zwei Zeichenfolgen verschachtelt ist.Einige mögliche Wege aufgelistet : Einfache generische Lösung:
StringUtils
Die KlassenfunktionsubstringBetween()
ruft den String ab, der zwischen zwei Strings verschachtelt ist. Es wird nur die erste Übereinstimmung zurückgegeben.Ersetzt die angegebene Zeichenfolge durch die Zeichenfolge, die zwischen zwei Zeichenfolgen verschachtelt ist.
#395
Der Punkt passt (fast) zu jedem Zeichen
.? = .{0,1}, .* = .{0,}, .+ = .{1,}
Regulärer Ausdruck mit der Utility-Klasse
RegexUtils
und 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.quelle
Verwendung :
quelle
Verwenden
Pattern and Matcher
quelle
Eine andere Möglichkeit, die Split-Methode zu verwenden
quelle
Der am wenigsten generische Weg, dies mit Regex- und Pattern / Matcher-Klassen zu tun:
Dies kann bei komplexeren Regex-Problemen hilfreich sein, bei denen Sie den Text zwischen zwei Zeichensätzen abrufen möchten.
quelle
quelle
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
String
und ich musste extrahieren<<UserName>>
Also,
indexOf
undStringUtils.substringBetween
war nicht hilfreich, da sie von Anfang an nach Charakter suchen.Also habe ich benutzt
lastIndexOf
Und es gibt mir
quelle
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.
quelle
Etwas wie das:
quelle
Es wird die ursprüngliche Zeichenfolge zurückgegeben, wenn kein übereinstimmender regulärer Ausdruck vorliegt
Fügen Sie dem Code Übereinstimmungen hinzu
quelle
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
quelle