Неправильный вывод с разделением строк

#java #arrays #regex #string

#java #массивы #регулярное выражение #строка

Вопрос:

Я написал эту простую программу, которая разделяет заданный ввод на каждый нецифровый символ.

 public class Fileread {
  public static void main(String[] args) throws IOException {
    //Declarations
    String[] temp;
    String current;

    //Execution
    BufferedReader br = new BufferedReader(new FileReader("input.txt"));
    while ((current = br.readLine()) != null) {
      temp = current.split("\D"); //Splitting at Non Digits
      for (int i = 0; i < temp.length; i  ) {
        System.out.println(temp[i]);
      }
    }
  }
}
 

Это input.txt :

 hello1world2  
world3  
end4of5world6 
 

Вывод :

 1




2





3



4

5




6
 

Почему появляется так много лишних пробелов? Мне нужно печатать каждое число в отдельной строке без пробелов между ними. Как я могу это исправить?

Комментарии:

1. Используйте \D шаблон. Однако начальный пустой элемент все равно может быть сохранен, если ваши строки начинаются с не цифр.

Ответ №1:

Он расщепляется на КАЖДУЮ не цифру.

Чтобы обрабатывать строки, не содержащие цифр, как один разделитель, укажите

 temp = current.split("\D ");
 

вместо этого. Добавление знака плюс приводит к совпадению шаблона с одним или несколькими последовательными нецифровыми символами.

Ответ №2:

 //Declarations
        String[] temp;
        String current;

        //Execution
        BufferedReader br = new BufferedReader(new FileReader("d://input.txt"));
        while ((current = br.readLine()) != null) {
            temp = current.split("\D "); //Splitting at Non Digits
            for (int i = 0; i < temp.length; i  ) {
                if (!temp[i].equalsIgnoreCase("")) {
                    System.out.println(temp[i]);
                }
            }
        }
 

Комментарии:

1. Это сработало! Это не сработает, если я поставлю !temp[i].equals(«») . Но это работает, если я ставлю !temp[i].equalsIgnoreCase(«») . В чем разница? Можете ли вы объяснить?

2. Мой плохой… Это работает для !temp [i] .также равно («») … Не пробовал… В любом случае, спасибо 🙂

Ответ №3:

Короче говоря, используйте

 .replaceFirst("^\D ","").split("\D ")
 

Разделение строки с D помощью (нецифрового шаблона сопоставления символов) означает, что вы сопоставляете один нецифровый символ за раз и разрываете строку на этом символе. Когда вам нужно разделить на фрагмент символов, вам нужно сопоставить несколько последовательных символов, и в вашем случае вам просто нужно добавить квантификатор после \D .

Однако это означает, что у вас все равно будет пустой элемент с индексом 0, если ваша строка содержит не цифру (ы) в начале строки. Обходным путем является удаление подстроки в начале с помощью шаблона разделения.

Окончательное решение

 List<String> strs = Arrays.asList("hello1world2", "world3", "end4of5world6");
for (String str : strs) {
    System.out.println("---- Next string ----");
    String[] temp = str.replaceFirst("^\D ","").split("\D ");
    for (String s: temp) {
        System.out.println(s);
    }
}
 

Посмотрите онлайн-демонстрацию Java

Ответ №4:

String#split Метод Java создаст токен для каждой точки, расположенной между двумя разделителями. Рассмотрим следующий пример:

 String s = "a,b,c,,,f";
 

Поскольку разделитель , появляется последовательно, между ними ничего нет, s.split(",") выдает следующий вывод:

 {"a", "b", "c", "", "", "f"}
 

Вы заметите, что в этом массиве есть две пустые строки; пробел вставляется для представления токена, который должен был появиться между каждой парой последовательных запятых. В принципе, строка обрабатывается как a,b,c,(blank),(blank),f .

Решение для этого состоит в том, чтобы последовательные разделители обрабатывались как один разделитель. Теперь важно помнить, что ваш аргумент to split на самом деле является литералом регулярного выражения. Таким образом, вы можете включить жадный квантификатор регулярных выражений, чтобы указать движку соответствие одному или нескольким последовательным разделителям и рассматривать их как единую точку разделения:

 s.split(", ")
 

Для приведенного выше примера это теперь дает следующее (без пустых строк):

 {"a", "b", "c", "f"}
 

Вы можете применить аналогичную технику к своему регулярному выражению, используя \D .