Как разбить строку в Java
У меня есть строка, "004-034556"
, что я хочу разбить на две строки:
string1="004";
string2="034556";
Это означает, что первая строка будет содержать символы перед '-'
, а вторая строка будет содержать символы после '-'
, Я также хочу проверить, есть ли строка '-'
в этом. Если нет, я брошу исключение. Как я могу это сделать?
39 ответов
Просто используйте соответствующий метод: String#split()
,
String string = "004-034556";
String[] parts = string.split("-");
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556
Обратите внимание, что для этого требуется регулярное выражение, поэтому не забудьте экранировать специальные символы, если это необходимо.
Есть 12 символов с особым значением: обратная косая черта
\
, каретка^
знак доллара$
, точка или точка.
, символ вертикальной черты или трубы|
знак вопроса?
, звездочка или звезда*
знак плюс+
открывающая скобка(
закрывающая скобка)
и открывающая квадратная скобка[
Открывающая фигурная скобка{
Эти специальные символы часто называют "метасимволами".
Итак, если вы хотите разделить, например, точка / точка .
что означает " любой символ " в регулярном выражении, используйте либо обратную косую черту \
чтобы избежать индивидуального специального персонажа, как так split("\\.")
или используйте класс символов []
представлять буквальный символ (ы), как так split("[.]")
или используйте Pattern#quote()
чтобы избежать всей строки, как это так split(Pattern.quote("."))
,
String[] parts = string.split(Pattern.quote(".")); // Split on period.
Чтобы предварительно проверить, содержит ли строка определенные символы, просто используйте String#contains()
,
if (string.contains("-")) {
// Split it.
} else {
throw new IllegalArgumentException("String " + string + " does not contain -");
}
Обратите внимание, это не требует регулярного выражения. Для этого используйте String#matches()
вместо.
Если вы хотите сохранить символ разделения в результирующих частях, используйте позитивный обходной путь. В случае, если вы хотите, чтобы символ разделения находился в левой части, используйте положительный вид сзади с префиксом ?<=
группа по шаблону.
String string = "004-034556";
String[] parts = string.split("(?<=-)");
String part1 = parts[0]; // 004-
String part2 = parts[1]; // 034556
В случае, если вы хотите, чтобы символ разделения находился справа, используйте положительный прогноз с префиксом ?=
группа по шаблону.
String string = "004-034556";
String[] parts = string.split("(?=-)");
String part1 = parts[0]; // 004
String part2 = parts[1]; // -034556
Если вы хотите ограничить количество получаемых частей, вы можете указать желаемое число в качестве второго аргумента split()
метод.
String string = "004-034556-42";
String[] parts = string.split("-", 2);
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556-42
Альтернативой прямой обработке строки было бы использование регулярного выражения с группами захвата. Это имеет то преимущество, что упрощает наложение более сложных ограничений на входные данные. Например, следующее разбивает строку на две части и гарантирует, что обе состоят только из цифр:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class SplitExample
{
private static Pattern twopart = Pattern.compile("(\\d+)-(\\d+)");
public static void checkString(String s)
{
Matcher m = twopart.matcher(s);
if (m.matches()) {
System.out.println(s + " matches; first part is " + m.group(1) +
", second part is " + m.group(2) + ".");
} else {
System.out.println(s + " does not match.");
}
}
public static void main(String[] args) {
checkString("123-4567");
checkString("foo-bar");
checkString("123-");
checkString("-4567");
checkString("123-4567-890");
}
}
Поскольку в этом случае шаблон является фиксированным, его можно скомпилировать заранее и сохранить как статический член (инициализированный во время загрузки класса в примере). Регулярное выражение:
(\d+)-(\d+)
Скобки обозначают группы захвата; Строка, которая соответствует этой части регулярного выражения, может быть доступна методом Match.group(), как показано. \ D соответствует и одной десятичной цифре, а + означает "соответствует одному или нескольким предыдущим выражениям.) - не имеет специального значения, поэтому просто соответствует этому символу во входных данных. Обратите внимание, что вам нужно дважды экранировать обратную косую черту при написании этого в виде строки Java. Некоторые другие примеры:
([A-Z]+)-([A-Z]+) // Each part consists of only capital letters
([^-]+)-([^-]+) // Each part consists of characters other than -
([A-Z]{2})-(\d+) // The first part is exactly two capital letters,
// the second consists of digits
String[] result = yourString.split("-");
if (result.length != 2)
throw new IllegalArgumentException("String not in correct format");
Это разделит вашу строку на 2 части. Первый элемент в массиве будет частью, содержащей материал перед -
, а 2-й элемент в массиве будет содержать часть вашей строки после -
,
Если длина массива не равна 2, то строка была не в формате: string-string
,
Проверьте split()
метод в String
учебный класс.
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
String[] out = string.split("-");
должен делать то, что вы хотите. Класс String имеет много методов для работы со строкой.
// This leaves the regexes issue out of question
// But we must remember that each character in the Delimiter String is treated
// like a single delimiter
public static String[] SplitUsingTokenizer(String subject, String delimiters) {
StringTokenizer strTkn = new StringTokenizer(subject, delimiters);
ArrayList<String> arrLis = new ArrayList<String>(subject.length());
while(strTkn.hasMoreTokens())
arrLis.add(strTkn.nextToken());
return arrLis.toArray(new String[0]);
}
С Java 8:
List<String> stringList = Pattern.compile("-")
.splitAsStream("004-034556")
.collect(Collectors.toList());
stringList.forEach(s -> System.out.println(s));
Используйте метод разделения org.apache.commons.lang.StringUtils, который может разбивать строки на основе символа или строки, которую вы хотите разделить.
Подпись метода:
public static String[] split(String str, char separatorChar);
В вашем случае вы хотите разбить строку, когда есть "-".
Вы можете просто сделать следующее:
String str = "004-034556";
String split[] = StringUtils.split(str,"-");
Выход:
004
034556
Предположим, что если -
не существует в вашей строке, он возвращает данную строку, и вы не получите никакого исключения.
Подводя итог: есть как минимум пять способов разбить строку в Java:
String.split ():
String[] parts ="10,20".split(",");
Pattern.compile (регулярное выражение).splitAsStream(вход):
List<String> strings = Pattern.compile("\\|") .splitAsStream("010|020202") .collect(Collectors.toList());
StringTokenizer (унаследованный класс):
StringTokenizer strings = new StringTokenizer("Welcome to EXPLAINJAVA.COM!", "."); while(strings.hasMoreTokens()){ String substring = strings.nextToken(); System.out.println(substring); }
Google Guava Splitter:
Iterable<String> result = Splitter.on(",").split("1,2,3,4");
Apache Commons StringUtils:
String[] strings = StringUtils.split("1,2,3,4", ",");
Таким образом, вы можете выбрать лучший вариант для вас, в зависимости от того, что вам нужно, например, тип возвращаемого значения (массив, список или итерируемый).
Вот большой обзор этих методов и наиболее распространенных примеров (как разделить на точки, косая черта, знак вопроса и т. Д.)
Требования оставили место для интерпретации. Я рекомендую написать метод,
public final static String[] mySplit(final String s)
которые инкапсулируют эту функцию. Конечно, вы можете использовать String.split (..), как указано в других ответах для реализации.
Вы должны написать несколько юнит-тестов для входных строк и желаемых результатов и поведения.
Хорошие тестовые кандидаты должны включать в себя:
- "0022-3333"
- "-"
- "5555-"
- "-333"
- "3344-"
- "--"
- ""
- "553535"
- "333-333-33"
- "222--222"
- "222--"
- "--4555"
Определив соответствующие результаты теста, вы можете указать поведение.
Например, если "-333"
должен вернуться в [,333]
или если это ошибка. Можно "333-333-33"
быть разделенным в [333,333-33] or [333-333,33]
или это ошибка? И так далее.
Вы можете попробовать так же
String concatenated_String="hi^Hello";
String split_string_array[]=concatenated_String.split("\\^");
При условии, что
- вам не нужны регулярные выражения для вашего раскола
- вы уже используете Apache Commons Lang в вашем приложении
Самый простой способ - использовать StringUtils # split (java.lang.String, char). Это удобнее, чем тот, который предоставляется Java из коробки, если вам не нужны регулярные выражения. Как сказано в его руководстве, он работает так:
A null input String returns null.
StringUtils.split(null, *) = null
StringUtils.split("", *) = []
StringUtils.split("a.b.c", '.') = ["a", "b", "c"]
StringUtils.split("a..b.c", '.') = ["a", "b", "c"]
StringUtils.split("a:b:c", '.') = ["a:b:c"]
StringUtils.split("a b c", ' ') = ["a", "b", "c"]
Я бы порекомендовал использовать commong-lang, так как обычно он содержит много полезного. Однако, если вам это не нужно для чего-то еще, кроме деления, тогда лучше реализовать себя или экранировать регулярное выражение.
Для простых случаев использования String.split()
должен сделать работу. Если вы используете guava, есть также класс Splitter, который позволяет связывать различные строковые операции и поддерживает CharMatcher:
Splitter.on('-')
.trimResults()
.omitEmptyStrings()
.split(string);
Самый быстрый способ, который также потребляет наименьшее количество ресурсов, может быть:
String s = "abc-def";
int p = s.indexOf('-');
if (p >= 0) {
String left = s.substring(0, p);
String right = s.substring(p + 1);
} else {
// s does not contain '-'
}
String Split с несколькими символами, используя Regex
public class StringSplitTest {
public static void main(String args[]) {
String s = " ;String; String; String; String, String; String;;String;String; String; String; ;String;String;String;String";
//String[] strs = s.split("[,\\s\\;]");
String[] strs = s.split("[,\\;]");
System.out.println("Substrings length:"+strs.length);
for (int i=0; i < strs.length; i++) {
System.out.println("Str["+i+"]:"+strs[i]);
}
}
}
Выход:
Substrings length:17
Str[0]:
Str[1]:String
Str[2]: String
Str[3]: String
Str[4]: String
Str[5]: String
Str[6]: String
Str[7]:
Str[8]:String
Str[9]:String
Str[10]: String
Str[11]: String
Str[12]:
Str[13]:String
Str[14]:String
Str[15]:String
Str[16]:String
Но не ожидайте одинакового вывода во всех версиях JDK. Я видел одну ошибку, которая существует в некоторых версиях JDK, где первая пустая строка была проигнорирована. Эта ошибка отсутствует в последней версии JDK, но существует в некоторых версиях между поздними версиями JDK 1.7 и ранними версиями 1.8.
public class SplitTest {
public static String[] split(String text, String delimiter) {
java.util.List<String> parts = new java.util.ArrayList<String>();
text += delimiter;
for (int i = text.indexOf(delimiter), j=0; i != -1;) {
String temp = text.substring(j,i);
if(temp.trim().length() != 0) {
parts.add(temp);
}
j = i + delimiter.length();
i = text.indexOf(delimiter,j);
}
return parts.toArray(new String[0]);
}
public static void main(String[] args) {
String str = "004-034556";
String delimiter = "-";
String result[] = split(str, delimiter);
for(String s:result)
System.out.println(s);
}
}
Есть только два метода, которые вы действительно должны рассмотреть.
Используйте String.split, если разделитель из одного символа, или вы не заботитесь о производительности
Если производительность не является проблемой, или если разделитель представляет собой один символ, который не является специальным символом регулярного выражения (т. Е. Не является одним из .$|()[{^?*+\
) тогда вы можете использовать String.split
,
String[] results = input.split(",");
Метод split имеет оптимизацию, позволяющую избежать использования регулярного выражения, если разделитель представляет собой один символ и отсутствует в приведенном выше списке. В противном случае он должен скомпилировать регулярное выражение, и это не идеально.
Используйте Pattern.split и прекомпилируйте шаблон, если используете сложный разделитель, и вы заботитесь о производительности
Если производительность является проблемой, а ваш разделитель не относится к числу перечисленных выше, вы должны предварительно скомпилировать шаблон регулярного выражения, который затем сможете использовать повторно.
// Save this somewhere
Pattern pattern = Pattern.compile("[,;:]");
/// ... later
String[] results = pattern.split(input);
Этот последний вариант все еще создает новый Matcher
объект. Вы также можете кэшировать этот объект и сбрасывать его для каждого входа для максимальной производительности, но это несколько сложнее и не поточно-ориентировано.
Вы можете разбить строку на разрыв строки, используя следующую инструкцию:
String textStr[] = yourString.split("\\r?\\n");
Вы можете разбить строку на дефис / символ, используя следующую инструкцию:
String textStr[] = yourString.split("-");
import java.io.*;
public class BreakString {
public static void main(String args[]) {
String string = "004-034556-1234-2341";
String[] parts = string.split("-");
for(int i=0;i<parts.length;i++) {
System.out.println(parts[i]);
}
}
}
Пожалуйста, не используйте класс StringTokenizer, так как это унаследованный класс, который сохраняется по соображениям совместимости, и его использование не рекомендуется в новом коде. И мы можем использовать метод разделения, как предложено другими.
String[] sampleTokens = "004-034556".split("-");
System.out.println(Arrays.toString(sampleTokens));
И, как ожидается, он напечатает:
[004, 034556]
В этом ответе я также хочу указать на одно изменение, которое произошло для split
метод в Java 8. Метод String#split() использует Pattern.split
и теперь он удалит пустые строки в начале массива результатов. Обратите внимание на это изменение в документации для Java 8:
Когда в начале входной последовательности имеется совпадение положительной ширины, в начале результирующего массива включается пустая ведущая подстрока. Однако совпадение с нулевой шириной в начале никогда не приводит к такой пустой ведущей подстроке.
Это означает для следующего примера:
String[] sampleTokensAgain = "004".split("");
System.out.println(Arrays.toString(sampleTokensAgain));
мы получим три строки: [0, 0, 4]
а не четыре, как было в Java 7 и раньше. Также проверьте этот похожий вопрос.
Один из способов сделать это - запустить строку в цикле for-each и использовать необходимый символ разделения.
public class StringSplitTest {
public static void main(String[] arg){
String str = "004-034556";
String split[] = str.split("-");
System.out.println("The split parts of the String are");
for(String s:split)
System.out.println(s);
}
}
Выход:
The split parts of the String are:
004
034556
Вы можете использовать Split():
import java.io.*;
public class Splitting
{
public static void main(String args[])
{
String Str = new String("004-034556");
String[] SplittoArray = Str.split("-");
String string1 = SplittoArray[0];
String string2 = SplittoArray[1];
}
}
Иначе, вы можете использовать StringTokenizer:
import java.util.*;
public class Splitting
{
public static void main(String[] args)
{
StringTokenizer Str = new StringTokenizer("004-034556");
String string1 = Str.nextToken("-");
String string2 = Str.nextToken("-");
}
}
Вот два способа достижения этого двумя.
ПУТЬ 1: Поскольку вам нужно разделить два числа специальным символом, вы можете использовать регулярное выражение
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TrialClass
{
public static void main(String[] args)
{
Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher("004-034556");
while(m.find())
{
System.out.println(m.group());
}
}
}
ПУТЬ 2: Использование метода разделения строк
public class TrialClass
{
public static void main(String[] args)
{
String temp = "004-034556";
String [] arrString = temp.split("-");
for(String splitString:arrString)
{
System.out.println(splitString);
}
}
}
Вы можете просто использовать StringTokenizer, чтобы разделить строку на две или более частей, независимо от того, существуют ли какие-либо разделители:
StringTokenizer st = new StringTokenizer("004-034556", "-");
while(st.hasMoreTokens())
{
System.out.println(st.nextToken());
}
String str="004-034556"
String[] sTemp=str.split("-");// '-' is a delimiter
string1=004 // sTemp[0];
string2=034556//sTemp[1];
Проверьте split()
метод в String
класс по javadoc.
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html
String data = "004-034556-1212-232-232";
int cnt = 1;
for (String item : data.split("-")) {
System.out.println("string "+cnt+" = "+item);
cnt++;
}
Здесь много примеров разбитой строки, но я немного оптимизировал код.
Я просто хотел написать алгоритм вместо использования встроенных функций Java:
public static List<String> split(String str, char c){
List<String> list = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++){
if(str.charAt(i) != c){
sb.append(str.charAt(i));
}
else{
if(sb.length() > 0){
list.add(sb.toString());
sb = new StringBuilder();
}
}
}
if(sb.length() >0){
list.add(sb.toString());
}
return list;
}
String s = "TnGeneral|DOMESTIC";
String a[]=s.split("\\|");
System.out.println(a.toString());
System.out.println(a[0]);
System.out.println(a[1]);
Выход:
TnGeneral
DOMESTIC
Вы можете использовать метод разделения
public class Demo {
public static void main(String args[]){
String str ="004-034556";
if((str.contains("-"))){
String[] temp=str.split("-");
for(String part:temp){
System.out.println(part);
}
}else{
System.out.println(str+" does not contain \"-\".");
}
}
}
Чтобы разбить строку, используется String.split(regex). Просмотрите следующие примеры:
String data = "004-034556";
String[] output = data.split("-");
System.out.println(output[0]);
System.out.println(output[1]);
Выход
004
034556
Примечание. Это разделение (регулярное выражение) принимает регулярное выражение в качестве аргумента, не забудьте экранировать специальные символы регулярного выражения, такие как точка / точка.
String s="004-034556";
for(int i=0;i<s.length();i++)
{
if(s.charAt(i)=='-')
{
System.out.println(s.substring(0,i));
System.out.println(s.substring(i+1));
}
}
Как уже упоминалось, split() - лучший вариант, который может быть использован в вашем случае. Альтернативным методом может быть использование substring().