Регулярное выражение с использованием нескольких повторяющихся групп захвата - PullRequest
2 голосов
/ 06 июля 2010

У меня очень унифицированный набор данных из сообщений Radius, которые мне нужно добавить в наше решение по управлению журналами. Продукт предлагает возможность использовать оператор регулярного выражения для извлечения различных данных в нескольких формах.

1) Отдельные регулярные выражения для каждого фрагмента данных, которые вы хотите извлечь

    <data 1 = regex statement>
    <data 2 = different regex statement>    
    <data 2 = yet another regex statement>

2) Сингулярное регулярное выражение с использованием групп захвата

    <group = regex statement with capture groups>
        <data 1 = capture group[X]
        <data 2 = capture group[Y]
        <data 3 = capture group[Z]
    </group>

<158>Jul 6 14:33:00 radius/10.10.100.12 radius: 07/06/2010 14:33:00 AP1A-BLAH (10.10.10.10) - 6191 / Wireless - IEEE 802.11: abc1234 - Access-Accept (AP: 000102030405 / SSID: bork / Client: 050403020100) 

Я хочу вытащить несколько бит данных, все они между пробелами. Что-то вроде следующего не кажется эффективным:

(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s

Итак, учитывая приведенные выше данные, какой самый эффективный Java Regex будет захватывать каждое поле между набором пробелов и помещать его в группу захвата?

Ответы [ 2 ]

2 голосов
/ 06 июля 2010

Вы могли бы быть более конкретным:

(\S*)\s(\S*)\s(\S*)\s(\S*)\s(\S*)\s(\S*)\s

\S соответствует непробельному символу - это делает регулярное выражение более эффективным, избегая обратного отслеживания, и позволяет регулярному выражению сбоить быстрее, если ввод не соответствует шаблону.

Т.е., когда вы применяете свое регулярное выражение к строке Jul 6 14:33:00 radius/10.10.100.12 radius: 07/06/2010, ему требуется 2116 шагов механизма регулярных выражений, чтобы определить, что оно не может совпадать. Выражение выше не выполняется в 168 шагов.

Предложение Алана Мура использовать (\S*+)\s(\S*+)\s(\S*+)\s(\S*+)\s(\S*+)\s(\S*+)\s приводит к еще одному улучшению - теперь регулярное выражение дает сбой в течение 24 шагов (почти в сто раз быстрее, чем первоначальное регулярное выражение).

Если совпадение прошло успешно, Алан и мое решение эквивалентны, ваше регулярное выражение примерно в десять раз медленнее.

1 голос
/ 06 июля 2010

Я просто подумал о другом - почему бы просто не разбить строку на пробел?

String[] splitArray = subjectString.split("\\s");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...