Java Scanner.nextLine () использует символ новой строки - PullRequest
4 голосов
/ 10 февраля 2012

У меня настроен сканер, который работает с InputStream.

Я использую Scanner.nextLine () для перехода к каждой строке, а затем выполняю некоторые операции с регулярными выражениями в каждой строке.

У меня есть регулярное выражение, которое в основном похоже на [\w\p{Z}]+?[;\n\r], чтобы забрать что-нибудь до конца этой строки или просто ОДНО, если они разделены точкой с запятой.

поэтому, если мой InpustStream будет выглядеть как

abcd;
xyz

Он подберет abcd ;, но не xyz.

Я думаю, это потому, что сканер использует символ новой строкиконец строки текста должен каким-то образом использоваться при вызове функции .nextLine ().Может кто-нибудь сказать мне, как решить эту проблему?

В качестве дополнительной информации, для моего регулярного выражения, я компилирую шаблон с Pattern.DOTALL

Спасибо!

Ответы [ 5 ]

5 голосов
/ 10 февраля 2012

На самом деле, именно вы вызываете проблему, пытаясь использовать новую строку в конце последней строки.: - / Совершенно верно, что последняя строка внезапно заканчивается без символа новой строки, но ваше регулярное выражение требует, чтобы она была.Возможно, вам удастся это исправить, заменив символ новой строки якорем или заглядыванием, но есть гораздо более простые способы сделать это.

Один - переопределить разделитель по умолчанию и перебрать поля с помощью next():

Scanner sc1 = new Scanner("abcd;\nxyz");
sc1.useDelimiter("[;\r\n]+");
while (sc1.hasNext())
{
  System.out.printf("%s%n", sc1.next());
}

Другой - перебрать строки с помощью nextLine() (используя разделитель по умолчанию)а затем разбить каждую строку на точки с запятой:

Scanner sc2 = new Scanner("abcd;\nxyz");
while (sc2.hasNextLine())
for (String item : sc2.nextLine().split(";"))
{
  System.out.printf("%s%n", item);
}

API сканера - один из самых раздутых и не интуитивно понятных, с которыми мне когда-либо приходилось работать, но вы можете значительно уменьшить боль от его использования, если помните эти два важныхОчки:

  1. Думайте с точки зрения соответствия разделителей , а не полей (как вы делаете с split() в String).
  2. Никогда не вызывайте один изnextXXX() методов без предварительного вызова соответствующего hasNextXXX() метода.
2 голосов
/ 10 февраля 2012

Итак, почему бы вам не добавить новую строку в ваш nextLine() результат?

Нет ли специального символа Regex ^ или $, обозначающего границы строк?

1 голос
/ 10 февраля 2012

API четко указывает, что следующая строка удаляет любой разделитель строк nextLine ()

Вы можете сделать одно из различных предложений в других ответах.Но также обратите внимание, что у сканера есть методы с «шаблоном».поэтому, если ваше регулярное выражение верно, вы можете использовать следующие методы:

hasNext (шаблон Pattern) или hasNext (String pattern) , чтобы определить, есть ли у вас больше токенов

, а затем

next (шаблон образца) или next (шаблон String) для получения токена, если приведенное выше вернул true.

1 голос
/ 10 февраля 2012

Символ регулярного выражения $ находит "конец шаблона". Сказав, что, поскольку у вас нет конца строки, легко потреблять все до первой точки с запятой; просто потребляйте все, кроме точки с запятой:

[^;]+

Scanner использует символ новой строки как часть его поведения, потому что вы обычно не хотите иметь с ним дело, и это зависит от системы.

Редактировать: В комментарии кто-то указал, что вы можете просто использовать line.split(";") и получить первое значение. Это тоже сработало бы.

0 голосов
/ 10 февраля 2012

Вы можете использовать \z в своем шаблоне регулярных выражений для обозначения конца ввода или $ для конца строки. Кроме того, Scanner.nextLine() по умолчанию возвращает строку без символа новой строки. Кроме того, вы можете изменить разделители, используемые вашим Scanner, чтобы включить ; с помощью метода useDelimiter. Наконец, ваш шаблон может не выполнять то, что вы думаете, так как \p{Z} ловит только буквы 'Z', судя по документации для Pattern.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...