2016-01-07 3 views
1

У меня есть строка, какРазбивает строку с разделителями запятыми без относительно запятых в скобках

s="abc, 3rncd (23uh, sdfuh), 32h(q23q)89 (as), dwe8h, edt (1,wer,345,rtz,tr t), nope"; 

, и я хочу, чтобы разбить его на те строки

String[] parts={"abc", "3rncd (23uh, sdfuh)", "32h(q23q)89 (as)", "dwe8h", "edt (1,wer,345,rtz,tr t)", "nope"}; 

Если я просто называю s.split(",") то после обрезки я получил бы другой результат, потому что в некоторых из этих строк, например "3rncd (23uh, sdfuh)", есть еще запятая. Но я не хочу, чтобы в скобках были запятые. Есть ли элегантный способ решить эту проблему?

+0

Возможный дубликат [Split строки в запятых кроме случаев, когда в среде кронштейном] (http://stackoverflow.com/questions/26808913/split -string-at-commas-except-when-in-bracket-environment) – Atri

+0

Кроме того, это python. –

+0

Не хотите ли вы игнорировать комы внутри кавычек? Не знаю python много, но csv parsing libs справляются с этим эффективно –

ответ

4

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

String[] arr = input.split(",(?![^()]*\\))\\s*"); 

RegEx Demo

,(?![^()]*\)) будет соответствовать запятая, если она не следует текст без скобок и ), игнорируя запятые внутри ( и ).

+0

В вашей демонстрации вы выбрали «pcre (php)». Это то, что использует Java? –

+0

Это просто для демонстрационной цели. Нет ничего PCRE, специфичного в '', (?! [^()] * \\)) \\ s * "', и он также работает на Java. – anubhava

+0

[Вот демонграмма Java-кода] (http://ideone.com/um74YQ) – anubhava

0

Даже это сработает для вас.

public static void main(String[] args) { 
    String s="abc, 3rncd (23uh, sdfuh), 32h(q23q)89 (as), dwe8h, edt (1,wer,345,rtz,tr t), nope"; 
    String[] arr = s.split(",\\s(?!\\w+\\))"); 
    for (String str : arr) { 
     System.out.println(str); 
    } 
} 

O/P:

abc 
3rncd (23uh, sdfuh) 
32h(q23q)89 (as) 
dwe8h 
edt (1,wer,345,rtz,tr t) 
nope 
0

FWIW: Я бы не использовать решение опережения для этого.

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

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

Каждый раз, когда регулярное выражение находит запятую, он должен сделать это (?![^()]*\))

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

Если у вас есть строка, как этот asdf,asdf,asdf,aasdf,aaaasdf,asdf,aasdf,asdf
прогрессия

Матч 1: найдено , смотрел вперед на все это asdf,asdf,aasdf,aaaasdf,asdf,aasdf,asdf
Матч 2: найдено , смотрел вперед на все это asdf,aasdf,aaaasdf,asdf,aasdf,asdf
Match 3: найдено , посмотрел вперед на все это aasdf,aaaasdf,asdf,aasdf,asdf
Матч 4: найдено , посмотрел вперед на все это aaaasdf,asdf,aasdf,asdf
Матч 5: найдено , смотрел вперед на все это asdf,aasdf,asdf
матча 6: найдено , смотрел вперед на все это aasdf,asdf
матча 7: найдено , смотрел вперед на все это asdf

Это довольно небольшой строка, соответствующая всем этим материалам.

Не рекомендуется использовать регулярное выражение для разделения или любого типа соответствия.


Я просто соответствовать значениям полей в глобальном поиске.

"(?:\\A|\\G,\\s*)([^(),]*(?:(?:\\([^()]*\\))[^(),]*)*)" 

Вот простой тест, который демонстрирует указанную задержку с использованием
опережения, как это может привести к:

Пример: 260 символов, 42 запятых

asdf,asdf,asdf,asdf,asdf,asdf,asdf, 
asdf,asdf,asdf,asdf,asdf,asdf,asdf, 
asdf,asdf,asdf,asdf,asdf,asdf,asdf, 
asdf,asdf,asdf,asdf,asdf,asdf,asdf, 
asdf,asdf,asdf,asdf,asdf,asdf,asdf, 
asdf,asdf,asdf,asdf,asdf,asdf,asdf, 
asdf,asdf,asdf,asdf,asdf,asdf,asdf, 

Benchmark

Regex1: (?:\A|\G,\s*)([^(),]*(?:(?:\([^()]*\))[^(),]*)*) 
Options: <none> 
Completed iterations: 50/50  (x 1000) 
Matches found per iteration: 50 
Elapsed Time: 2.97 s, 2972.45 ms, 2972454 µs 


Regex2: ,(?![^()]*\))\s* 
Options: <none> 
Completed iterations: 50/50  (x 1000) 
Matches found per iteration: 49 
Elapsed Time: 21.59 s, 21586.81 ms, 21586811 µs 

Когда образец удваивается, время становится когда-либо хуже ..

Regex1: (?:\A|\G,\s*)([^(),]*(?:(?:\([^()]*\))[^(),]*)*) 
Options: <none> 
Completed iterations: 50/50  (x 1000) 
Matches found per iteration: 99 
Elapsed Time: 5.89 s, 5887.16 ms, 5887163 µs 


Regex2: ,(?![^()]*\))\s* 
Options: <none> 
Completed iterations: 50/50  (x 1000) 
Matches found per iteration: 98 
Elapsed Time: 83.06 s, 83063.77 ms, 83063772 µs 
Смежные вопросы