Как сделать так, чтобы сканер возвращал разделители как токены - PullRequest
1 голос
/ 30 октября 2019

Я пытаюсь использовать java.util.Scanner для токенизации арифметического выражения, где разделителями могут быть:

  • Пробел (\s+ или \p{Space}+),который должен быть отброшен
  • Пунктуация (\p{Punct}), который должен быть возвращен как токен

Пример

С учетом этого выражения:

12 + (ab-bc*3)

Я бы хотел, чтобы Сканер вернул следующие токены:

  • 12
  • +
  • (
  • ab
  • -
  • bc
  • *
  • 3
  • )

Код

До сих пор я мог только:

  • Съесть все знаки препинания (не то, что я хотел):
    • new Scanner("12 + (ab-bc*3)").useDelimiter("\\p{Space}+|\\p{Punct}").tokens().collect(Collectors.toList())
    • Результат: "12", "", "", "", "ab", "bc", "3"
  • Достигнуть частичного успеха, используя позитивный прогноз
    • new Scanner("12 + (ab-bc*3)").useDelimiter("\\p{Space}+|(?=\\p{Punct})").tokens().collect(Collectors.toList())
    • Результат: "12", "+", "(ab", "-bc", "*3", ")"

Но теперь я застрял.

1 Ответ

4 голосов
/ 30 октября 2019

A подход позволяет использовать здесь гораздо более простое регулярное выражение:

String text = "12 + (ab-bc*3)";
List<String> results = Pattern.compile("\\p{Punct}|\\w+").matcher(text)
    .results()
    .map(MatchResult::group)
    .collect(Collectors.toList());
System.out.println(results); 
// => "12", "+", "(", "ab", "-", "bc", "*", "3", ")"

См. Java demo .

Регулярное выражение соответствует

  • \p{Punct} - знаки препинания и символы
  • | - или
  • \w+ - 1+ буквы, цифры или_ символов.

См. Демонстрационный пример регулярных выражений (преобразован в PCRE для демонстрационной цели).

...