Использование String.split () Как разделить строку на основе регулярного выражения, исключая определенную строку - PullRequest
6 голосов
/ 19 января 2020

У меня есть эта строка:

"round((TOTAL_QTY * 100) / SUM(ORDER_ITEMS->TOTAL_QTY) , 1)"

Я попытался разбить строку, используя следующий код:

String[] tokens = function.split("[ )(*+-/^!@#%&]");

Результатом является следующий массив:

"round"
""
"TOTAL_QTY"
""
""
"100"
""
""
""
"SUM"
"ORDER_ITEMS"
"->TOTAL_QTY"
""
""
""
"1"

Но мне нужно разбить строку следующим образом:

"round",
"TOTAL_QTY",
"100",
"SUM",
"ORDER_ITEMS->TOTAL_QTY",
"1"

Чтобы было понятнее. Прежде всего мне нужно игнорировать ->, когда он разбивает строку, а затем удалять эти пустые строки в массиве результатов.

Ответы [ 3 ]

4 голосов
/ 19 января 2020

Решение 1

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

[)(*+/^!@#%&,]|\\b-\\b

Ваш код:

String[] tokens = function.replaceAll("[)(*+/^!@#%&,]|\\b-\\b", " ").split("\\s+");

Обратите внимание, что я использовал \\b-\\b для замены только -:

Решение 2

Или Если вы хотите что-то чистое Вы можете использовать Pattern с Matcher следующим образом:

Pattern.compile("\\b\\w+->\\w+\\b|\\b\\w+\\b")
        .matcher("round((TOTAL_QTY * 100) / SUM(ORDER_ITEMS->TOTAL_QTY) , 1)")
        .results()
        .map(MatchResult::group)
        .forEach(s -> System.out.println(String.format("\"%s\"", s)));

regex demo

Details

  • \b\w+->\w+\b для соответствия этому особому случаю ORDER_ITEMS->TOTAL_QTY
  • | или
  • \b\w+\b любому другому слову с границами слова

Обратите внимание, это решение работает из Java9 +, но вы можете использовать простое решение Pattern and Matcher.

Выходы

"round"
"TOTAL_QTY"
"100"
"SUM"
"ORDER_ITEMS->TOTAL_QTY"
"1"
2 голосов
/ 19 января 2020

Можно увидеть пару очень хороших решений от YCF_L

Вот еще одно решение:

String[] tokens = function.replace(")","").split("\\(+|\\*|/|,");

Объяснение:

\\(+ будет разделен на (, а + обеспечит, что несколько открытых скобок будут обработаны, например, round((

|\\*|/|, ИЛИ разделен на * ИЛИ разделен на / ИЛИ разделен на ,

Выход:

round
TOTAL_QTY 
100 
SUM
ORDER_ITEMS->TOTAL_QTY 
1
0 голосов
/ 19 января 2020

вам нужно очистить вывод вашего метода разбиения:

List<String> result =
                Arrays.asList(tokens).stream()
                      .filter(st -> st.length() > 0)
                      .map( str-> str.replace('>',' ').trim())
                      .collect(Collectors.toList());

результат

[round, TOTAL_QTY, 100, SUM, ORDER_ITEMS, TOTAL_QTY, 1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...