Hay varias maneras - se podía repetir los caracteres en la cadena hasta llegar a la (o encontrar el índice de la primera (y )y hacerlo con la subcadena o, lo que la mayoría de la gente haría, utilice una expresión regular.
Andreas Dolk
Respuestas:
103
Probablemente haya una expresión regular realmente buena, pero soy un novato en esa área, así que en cambio ...
String s = "test string (67)";
s = s.substring(s.indexOf("(") + 1);
s = s.substring(0, s.indexOf(")"));
System.out.println(s);
Sin pasar por las rarezas del análisis de expresiones regulares, creo que esta es la mejor manera de extraer la cadena requerida.
verosimilitud
3
regex es mucho más poderoso y puede tomar en más casos, pero para simplificar, esto funciona ...
MadProgrammer
2
En serio, ¿por qué esto atraería un voto negativo? ¿No funciona? ¿No responde a la pregunta de operaciones?
MadProgrammer
si tengo varios valores, ¿cómo puedo usar la subcadena? Considere que tengo una cadena como esta 'this is an example of <how><i have it>'y necesito encontrar valores entre '<' y '>' esto
Vignesh
@Vignesh Use una expresión regular
MadProgrammer
74
Una solución muy útil a este problema que no requiere que haga el indexOf es usar las bibliotecas de Apache Commons .
StringUtils.substringBetween(s, "(", ")");
Este método le permitirá incluso manejar incluso si hay múltiples apariciones de la cadena de cierre, lo que no será fácil al buscar indexOf cadena de cierre.
Creo que deberías hacer de esta una coincidencia no codiciosa usando ". *?" en lugar. De lo contrario, si la cadena se soemthing como "cadena de prueba (67) y (68), esto devolverá "67) y (68".
Chthonic Proyecto
18
Java admite expresiones regulares , pero son un poco engorrosas si realmente desea usarlas para extraer coincidencias. Creo que la forma más fácil de llegar a la cadena que desea en su ejemplo es simplemente usar el soporte de Expresión regular en el método de la Stringclase replaceAll:
String x = "test string (67)".replaceAll(".*\\(|\\).*", "");
// x is now the String "67"
Esto simplemente elimina todo, incluido el primero (, y lo mismo para el )y todo lo que sigue. Esto solo deja las cosas entre paréntesis.
Sin embargo, el resultado de esto sigue siendo un String. Si desea un resultado entero en su lugar, debe hacer otra conversión:
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
Formatee su código sangrando 4 espacios. También quisiera rellenar un poco su respuesta explicando qué hace su código para aquellos visitantes que no están seguros de qué hace .substringy .indexOf`.
Bugs
6
Cadena de prueba test string (67)de la que necesita obtener la cadena que está anidada entre dos cadenas.
String str = "test string (67) and (77)", open = "(", close = ")";
Enumeró algunas formas posibles : Solución genérica simple:
String subStr = str.substring(str.indexOf( open ) + 1, str.indexOf( close ));
System.out.format("String[%s] Parsed IntValue[%d]\n", subStr, Integer.parseInt( subStr ));
Regular-Expression con la clase de utilidad RegexUtilsy algunas funciones. Pattern.DOTALL: Coincide con cualquier carácter, incluido un terminador de línea. Pattern.MULTILINE: Coincide con la cadena completa desde el principio ^hasta el final $de la secuencia de entrada.
publicstatic String generateRegex(String open, String close){
return"(" + RegexUtils.escapeQuotes(open) + ")(.*?)(" + RegexUtils.escapeQuotes(close) + ").*";
}
publicstatic 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;
}
La forma menos genérica que encontré para hacer esto con las clases Regex y Pattern / Matcher:
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, ""));
}
Esto puede ayudar para problemas de expresiones regulares más complejos en los que desea obtener el texto entre dos conjuntos de caracteres.
La forma "genérica" de hacer esto es analizar la cadena desde el principio, desechando todos los caracteres antes del primer corchete, registrando los caracteres después del primer corchete y desechando los caracteres después del segundo corchete.
Estoy seguro de que hay una biblioteca de expresiones regulares o algo para hacerlo.
(
o encontrar el índice de la primera(
y)
y hacerlo con la subcadena o, lo que la mayoría de la gente haría, utilice una expresión regular.Respuestas:
Probablemente haya una expresión regular realmente buena, pero soy un novato en esa área, así que en cambio ...
String s = "test string (67)"; s = s.substring(s.indexOf("(") + 1); s = s.substring(0, s.indexOf(")")); System.out.println(s);
fuente
'this is an example of <how><i have it>'
y necesito encontrar valores entre '<' y '>' estoUna solución muy útil a este problema que no requiere que haga el indexOf es usar las bibliotecas de Apache Commons .
StringUtils.substringBetween(s, "(", ")");
Este método le permitirá incluso manejar incluso si hay múltiples apariciones de la cadena de cierre, lo que no será fácil al buscar indexOf cadena de cierre.
Puede descargar esta biblioteca desde aquí: https://mvnrepository.com/artifact/org.apache.commons/commons-lang3/3.4
fuente
substringsBetween(...)
si esperas múltiples resultados, que es lo que estaba buscando. GraciasPruébalo así
String s="test string(67)"; String requiredString = s.substring(s.indexOf("(") + 1, s.indexOf(")"));
La firma del método para la subcadena es:
s.substring(int start, int end);
fuente
Usando expresión regular:
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));
fuente
Java admite expresiones regulares , pero son un poco engorrosas si realmente desea usarlas para extraer coincidencias. Creo que la forma más fácil de llegar a la cadena que desea en su ejemplo es simplemente usar el soporte de Expresión regular en el método de la
String
clasereplaceAll
:String x = "test string (67)".replaceAll(".*\\(|\\).*", ""); // x is now the String "67"
Esto simplemente elimina todo, incluido el primero
(
, y lo mismo para el)
y todo lo que sigue. Esto solo deja las cosas entre paréntesis.Sin embargo, el resultado de esto sigue siendo un
String
. Si desea un resultado entero en su lugar, debe hacer otra conversión:int n = Integer.parseInt(x); // n is now the integer 67
fuente
En una sola línea, sugiero:
String input = "test string (67)"; input = input.subString(input.indexOf("(")+1, input.lastIndexOf(")")); System.out.println(input);`
fuente
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
fuente
Puede usar StringUtils de la biblioteca común de Apache para hacer esto.
import org.apache.commons.lang3.StringUtils; ... String s = "test string (67)"; s = StringUtils.substringBetween(s, "(", ")"); ....
fuente
String result = s.substring(s.indexOf("(") + 1, s.indexOf(")"));
fuente
.substring
y .indexOf`.Cadena de prueba
test string (67)
de la que necesita obtener la cadena que está anidada entre dos cadenas.String str = "test string (67) and (77)", open = "(", close = ")";
Enumeró algunas formas posibles : Solución genérica simple:
String subStr = str.substring(str.indexOf( open ) + 1, str.indexOf( close )); System.out.format("String[%s] Parsed IntValue[%d]\n", subStr, Integer.parseInt( subStr ));
StringUtils
LasubstringBetween()
función de clase obtiene la cadena que está anidada entre dos cadenas. Solo se devuelve la primera coincidencia.String substringBetween = StringUtils.substringBetween(subStr, open, close); System.out.println("Commons Lang3 : "+ substringBetween);
Reemplaza la cadena dada por la cadena que está anidada entre dos cadenas.
#395
El punto coincide (casi) con cualquier personaje
.? = .{0,1}, .* = .{0,}, .+ = .{1,}
String patternMatch = patternMatch(generateRegex(open, close), str); System.out.println("Regular expression Value : "+ patternMatch);
Regular-Expression con la clase de utilidad
RegexUtils
y algunas funciones.Pattern.DOTALL
: Coincide con cualquier carácter, incluido un terminador de línea.Pattern.MULTILINE
: Coincide con la cadena completa desde el principio^
hasta el final$
de la secuencia de entrada.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; }
fuente
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 "" ; }
Uso:
String input = "test string (67)"; String startChar = "("; String endChar = ")"; String output = getStringBetweenTwoChars(input, startChar, endChar); System.out.println(output); // Output: "67"
fuente
Utilizar
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); } }
fuente
Otra forma de hacerlo usando el método dividido
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]); }
fuente
La forma menos genérica que encontré para hacer esto con las clases Regex y Pattern / Matcher:
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, "")); }
Esto puede ayudar para problemas de expresiones regulares más complejos en los que desea obtener el texto entre dos conjuntos de caracteres.
fuente
La forma "genérica" de hacer esto es analizar la cadena desde el principio, desechando todos los caracteres antes del primer corchete, registrando los caracteres después del primer corchete y desechando los caracteres después del segundo corchete.
Estoy seguro de que hay una biblioteca de expresiones regulares o algo para hacerlo.
fuente
String s = "test string (67)"; System.out.println(s.substring(s.indexOf("(")+1,s.indexOf(")")));
fuente
La otra solución posible es usar
lastIndexOf
donde buscará el carácter o la Cadena desde atrás.En mi escenario, tenía seguimiento
String
y tuve que extraer<<UserName>>
1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc
Entonces,
indexOf
yStringUtils.substringBetween
no fue útil ya que comenzaron a buscar el personaje desde el principio.Entonces, usé
lastIndexOf
String str = "1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc"; String userName = str.substring(str.lastIndexOf("_") + 1, str.lastIndexOf("."));
Y me da
fuente
Algo como esto:
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; }
fuente
Esta es una
\D+
expresión regular de uso simple y trabajo hecho.Esto selecciona todos los caracteres excepto los dígitos, no es necesario complicar
fuente
devolverá la cadena original si no coincide con la expresión regular
var iAm67 = "test string (67)".replaceFirst("test string \\((.*)\\)", "$1");
agregar coincidencias al código
String str = "test string (67)"; String regx = "test string \\((.*)\\)"; if (str.matches(regx)) { var iAm67 = str.replaceFirst(regx, "$1"); }
---EDITAR---
yo uso https://www.freeformatter.com/java-regex-tester.html#ad-output para probar regex.
resulta que es mejor agregar? después de * para menos partido. algo como esto:
String str = "test string (67)(69)"; String regx1 = "test string \\((.*)\\).*"; String regx2 = "test string \\((.*?)\\).*"; String ans1 = str.replaceFirst(regx1, "$1"); String ans2 = str.replaceFirst(regx2, "$1"); System.out.println("ans1:"+ans1+"\nans2:"+ans2); // ans1:67)(69 // ans2:67
fuente