Il y a plusieurs façons - vous pouvez itérer les caractères dans la chaîne jusqu'à ce que vous atteignez le (ou trouver l'indice de la première (et )et le faire avec ou sous - chaîne, ce que la plupart des gens, utilisez une expression régulière.
Andreas Dolk
Réponses:
103
Il y a probablement un RegExp vraiment sympa, mais je ne suis pas du tout dans ce domaine, alors à la place ...
String s = "test string (67)";
s = s.substring(s.indexOf("(") + 1);
s = s.substring(0, s.indexOf(")"));
System.out.println(s);
Sans passer par les bizarreries de l'analyse des regex, je pense que c'est le meilleur moyen d'extraire la chaîne requise.
vérisimilitude du
3
regex est de loin plus puissant et peut prendre dans plus de cas, mais pour plus de simplicité, cela fonctionne ...
MadProgrammer
2
Sérieusement, pourquoi cela attirerait-il un vote négatif? Ça ne marche pas? Cela ne répond-il pas à la question des opérations?
MadProgrammer
si j'ai plusieurs valeurs, comment puis-je utiliser une sous-chaîne, considérer que j'ai une chaîne comme celle-ci 'this is an example of <how><i have it>'et que j'ai besoin de trouver des valeurs entre '<' et '>' this
Vignesh
@Vignesh Utiliser une expression régulière
MadProgrammer
74
Une solution très utile à ce problème qui ne vous oblige pas à faire l'indexOf utilise les bibliothèques Apache Commons .
StringUtils.substringBetween(s, "(", ")");
Cette méthode vous permettra même de gérer même s'il existe plusieurs occurrences de la chaîne de fermeture, ce qui ne sera pas facile en recherchant la chaîne de fermeture indexOf.
Je pense que vous devriez en faire une correspondance non gourmande en utilisant ". *?" au lieu. Sinon, si la chaîne est quelque chose comme "test string (67) et (68), cela renverra" 67) et (68 ".
Chthonic Project
18
Java prend en charge les expressions régulières , mais elles sont plutôt lourdes si vous voulez réellement les utiliser pour extraire des correspondances. Je pense que le moyen le plus simple d'obtenir la chaîne souhaitée dans votre exemple consiste simplement à utiliser le support des expressions régulières dans la méthode de la Stringclasse replaceAll:
String x = "test string (67)".replaceAll(".*\\(|\\).*", "");
// x is now the String "67"
Cela supprime simplement tout, y compris le premier (, et de même pour le )et tout par la suite. Cela laisse juste les choses entre les parenthèses.
Cependant, le résultat de ceci est toujours un String. Si vous voulez un résultat entier à la place, vous devez effectuer une autre conversion:
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
Veuillez formater votre code en indentant 4 espaces. Aussi, je voudrais compléter votre réponse un peu en expliquant ce que votre code fait pour ceux qui ne savent pas ce que fait .substringet .indexOf`.
Bugs
6
Chaîne test string (67)de test à partir de laquelle vous devez obtenir la chaîne imbriquée entre deux chaînes.
String str = "test string (67) and (77)", open = "(", close = ")";
Énuméré quelques moyens possibles : Solution générique 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 ));
StringUtilsLa substringBetween()fonction de classe obtient la chaîne qui est imbriquée entre deux chaînes. Seule la première correspondance est renvoyée.
Expression régulière avec la classe utilitaire RegexUtilset certaines fonctions. Pattern.DOTALL: Correspond à n'importe quel caractère, y compris une terminaison de ligne. Pattern.MULTILINE: Correspond à la chaîne entière du début ^à la fin $de la séquence d'entrée.
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;
}
Le moyen le moins générique que j'ai trouvé pour le faire avec les classes Regex et 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, ""));
}
Cela peut aider pour des problèmes de regex plus complexes où vous souhaitez obtenir le texte entre deux jeux de caractères.
La manière "générique" de faire ceci est d'analyser la chaîne depuis le début, de jeter tous les caractères avant le premier crochet, d'enregistrer les caractères après le premier crochet et de jeter les caractères après le deuxième crochet.
Je suis sûr qu'il existe une bibliothèque de regex ou quelque chose pour le faire.
Ceci est une \D+expression régulière d' utilisation simple et un travail fait.
Cela sélectionne tous les caractères sauf les chiffres, pas besoin de compliquer
(
ou trouver l'indice de la première(
et)
et le faire avec ou sous - chaîne, ce que la plupart des gens, utilisez une expression régulière.Réponses:
Il y a probablement un RegExp vraiment sympa, mais je ne suis pas du tout dans ce domaine, alors à la place ...
String s = "test string (67)"; s = s.substring(s.indexOf("(") + 1); s = s.substring(0, s.indexOf(")")); System.out.println(s);
la source
'this is an example of <how><i have it>'
et que j'ai besoin de trouver des valeurs entre '<' et '>' thisUne solution très utile à ce problème qui ne vous oblige pas à faire l'indexOf utilise les bibliothèques Apache Commons .
StringUtils.substringBetween(s, "(", ")");
Cette méthode vous permettra même de gérer même s'il existe plusieurs occurrences de la chaîne de fermeture, ce qui ne sera pas facile en recherchant la chaîne de fermeture indexOf.
Vous pouvez télécharger cette bibliothèque depuis ici: https://mvnrepository.com/artifact/org.apache.commons/commons-lang3/3.4
la source
substringsBetween(...)
si vous attendez plusieurs résultats, c'est ce que je recherchais. MerciEssayez-le comme ça
String s="test string(67)"; String requiredString = s.substring(s.indexOf("(") + 1, s.indexOf(")"));
La signature de la méthode pour la sous-chaîne est:
s.substring(int start, int end);
la source
En utilisant une expression régulière:
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));
la source
Java prend en charge les expressions régulières , mais elles sont plutôt lourdes si vous voulez réellement les utiliser pour extraire des correspondances. Je pense que le moyen le plus simple d'obtenir la chaîne souhaitée dans votre exemple consiste simplement à utiliser le support des expressions régulières dans la méthode de la
String
classereplaceAll
:String x = "test string (67)".replaceAll(".*\\(|\\).*", ""); // x is now the String "67"
Cela supprime simplement tout, y compris le premier
(
, et de même pour le)
et tout par la suite. Cela laisse juste les choses entre les parenthèses.Cependant, le résultat de ceci est toujours un
String
. Si vous voulez un résultat entier à la place, vous devez effectuer une autre conversion:int n = Integer.parseInt(x); // n is now the integer 67
la source
En une seule ligne, je propose:
String input = "test string (67)"; input = input.subString(input.indexOf("(")+1, input.lastIndexOf(")")); System.out.println(input);`
la source
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
la source
Vous pouvez utiliser StringUtils de la bibliothèque commune apache pour ce faire.
import org.apache.commons.lang3.StringUtils; ... String s = "test string (67)"; s = StringUtils.substringBetween(s, "(", ")"); ....
la source
String result = s.substring(s.indexOf("(") + 1, s.indexOf(")"));
la source
.substring
et .indexOf`.Chaîne
test string (67)
de test à partir de laquelle vous devez obtenir la chaîne imbriquée entre deux chaînes.String str = "test string (67) and (77)", open = "(", close = ")";
Énuméré quelques moyens possibles : Solution générique 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()
fonction de classe obtient la chaîne qui est imbriquée entre deux chaînes. Seule la première correspondance est renvoyée.String substringBetween = StringUtils.substringBetween(subStr, open, close); System.out.println("Commons Lang3 : "+ substringBetween);
Remplace la chaîne donnée par la chaîne imbriquée entre deux chaînes.
#395
Le point correspond (presque) à n'importe quel caractère
.? = .{0,1}, .* = .{0,}, .+ = .{1,}
String patternMatch = patternMatch(generateRegex(open, close), str); System.out.println("Regular expression Value : "+ patternMatch);
Expression régulière avec la classe utilitaire
RegexUtils
et certaines fonctions.Pattern.DOTALL
: Correspond à n'importe quel caractère, y compris une terminaison de ligne.Pattern.MULTILINE
: Correspond à la chaîne entière du début^
à la fin$
de la séquence d'entrée.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; }
la source
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 "" ; }
Utilisation:
String input = "test string (67)"; String startChar = "("; String endChar = ")"; String output = getStringBetweenTwoChars(input, startChar, endChar); System.out.println(output); // Output: "67"
la source
Utilisation
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); } }
la source
Une autre façon de faire en utilisant la méthode fractionnée
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]); }
la source
Le moyen le moins générique que j'ai trouvé pour le faire avec les classes Regex et 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, "")); }
Cela peut aider pour des problèmes de regex plus complexes où vous souhaitez obtenir le texte entre deux jeux de caractères.
la source
La manière "générique" de faire ceci est d'analyser la chaîne depuis le début, de jeter tous les caractères avant le premier crochet, d'enregistrer les caractères après le premier crochet et de jeter les caractères après le deuxième crochet.
Je suis sûr qu'il existe une bibliothèque de regex ou quelque chose pour le faire.
la source
String s = "test string (67)"; System.out.println(s.substring(s.indexOf("(")+1,s.indexOf(")")));
la source
L'autre solution possible est d'utiliser
lastIndexOf
où il recherchera un caractère ou une chaîne à partir de l'arrière.Dans mon scénario, j'ai suivi
String
et j'ai dû extraire<<UserName>>
1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc
Donc,
indexOf
et celaStringUtils.substringBetween
n'a pas été utile car ils commencent à chercher du personnage depuis le début.Alors, j'ai utilisé
lastIndexOf
String str = "1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc"; String userName = str.substring(str.lastIndexOf("_") + 1, str.lastIndexOf("."));
Et ça me donne
la source
Quelque chose comme ça:
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; }
la source
Ceci est une
\D+
expression régulière d' utilisation simple et un travail fait.Cela sélectionne tous les caractères sauf les chiffres, pas besoin de compliquer
la source
il retournera la chaîne d'origine si aucune expression régulière ne correspond
var iAm67 = "test string (67)".replaceFirst("test string \\((.*)\\)", "$1");
ajouter des correspondances au code
String str = "test string (67)"; String regx = "test string \\((.*)\\)"; if (str.matches(regx)) { var iAm67 = str.replaceFirst(regx, "$1"); }
---ÉDITER---
j'utilise https://www.freeformatter.com/java-regex-tester.html#ad-output pour tester regex.
s'avère qu'il vaut mieux ajouter? après * pour moins de correspondance. quelque chose comme ça:
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
la source