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?
Antworten:
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);
'this is an example of <how><i have it>'
ich Werte zwischen '<' und '>' this
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
substringsBetween(...)
wenn Sie mehrere Ergebnisse erwarten, was ich gesucht habe. Vielen Dank
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);
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));
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 zu replaceAll
verwenden:
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
In einer einzigen Zeile schlage ich vor:
String input = "test string (67)";
input = input.subString(input.indexOf("(")+1, input.lastIndexOf(")"));
System.out.println(input);`
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
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, "(", ")");
....
String result = s.substring(s.indexOf("(") + 1, s.indexOf(")"));
.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.
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
.
StringUtils
Die 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 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.
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;
}
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"
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);
}
}
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.
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>>
1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc
Also, indexOf
und StringUtils.substringBetween
war 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>>
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.
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;
}
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");
}
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+/
(
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.