2015-05-03 2 views
4

Я пытаюсь соответствовать что-то вродеRegex времени из

foo: anything after the colon can be matched with (.*)+ 
foo.bar1.BAZ: balh5317{}({}(

Это регулярное выражение я использую:

/^((?:(?:(?:[A-Za-z_]+)(?:[0-9]+)?)+[\.]?)+)(?:\s)?(?:\:)(?:\s)?((?:.*)+)$/ 

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

Это работает на примерах. Проблема возникает, когда я пытаюсь поставить в строку, как это:

foo.bar.baz.beef.stew.ect.and.forward 

мне нужно, чтобы быть в состоянии проверить строки, как это, но раз регулярное выражение двигателя из или работает бесконечность (насколько я могу сказать) после того, как определенное количество foo. s каждый раз.

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

Кроме того, здесь более подробное описание того, что мне нужно, чтобы соответствовать:

Property Name: can contain A-z, numbers, and underscores but can't start with a number 

<Property Name>.<Property Name>.<Prop...:<Anything after the colon> 

Спасибо за ваше время!

+0

Когда я попытался написать его с нуля, я пришел с '\ Ь ((?: [A-Za-Z _] [A-Za-z_0-9] * \.?) * [A-Za-z _] [A-Za-z_0-9] *): (. +) ', Который работает, но почти такой же, как ваш RegEx ... нет бесконечного цикла, который происходит с этим http://regex101.com. Но я могу подтвердить тайм-аут для вашего RegEx! – Xufox

+0

Хорошо, так что, видимо, это работает, если эти метки '^' и '$ 'удаляются и вместо этого установлен флаг' g'. – Xufox

+1

Я думаю, что это актуально: [Катастрофическое откат] (http://www.regular-expressions.info/catastrophic.html). – Xufox

ответ

2

Начиная с регулярным выражением:

^((?:(?:(?:[A-Za-z_]+)(?:[0-9]+)?)+[\.]?)+)(?:\s)?(?:\:)(?:\s)?((?:.*)+)$ 


^         # Anchors to the beginning to the string. 
(         # Opens CG1 
    (?:       # Opens NCG 
     (?:      # Opens NCG 
      (?:     # Opens NCG 
       [A-Za-z_]+   # Character class (any of the characters within) 
      )      # Closes NCG 
      (?:     # Opens NCG 
       [0-9]+    # Character class (any of the characters within) 
      )?      # Closes NCG 
     )+       # Closes NCG 
     [\.]?      # Character class (any of the characters within) 
    )+        # Closes NCG 
)         # Closes CG1 
(?:        # Opens NCG 
    \s        # Token: \s (white space) 
)?         # Closes NCG 
(?:        # Opens NCG 
    \:        # Literal : 
)         # Closes NCG 
(?:        # Opens NCG 
    \s        # Token: \s (white space) 
)?         # Closes NCG 
(         # Opens CG2 
    (?:       # Opens NCG 
     .*       # . denotes any single character, except for newline 
    )+        # Closes NCG 
)         # Closes CG2 
$         # Anchors to the end to the string. 

я преобразовал [0-9] в \d, просто для облегчения читаемости (оба совпадают то же самое). Я также удалил много не захватывающих групп, потому что они на самом деле не использовались.

^((?:(?:[A-Za-z_]+\d*)+\.?)+)\s?\:\s?((?:.*)+)$ 

Я также объединил \s и. * В [\s\S]*, но, видя, что он последовал + знак, я удалил группу и просто сделал [\s\S].

^((?:(?:[A-Za-z_]+\d*)+\.?)+)\s?\:([\s\S]+)$ 
        ^

Теперь я не уверен, что + выше карата должен делать. Мы можем удалить его и, таким образом, группу, не связанную с захватом.

^((?:[A-Za-z_]+\d*\.?)+)\s?\:([\s\S]+)$ 

Объяснение:

^      # Anchors to the beginning to the string. 
(       # Opens CG1 
    (?:     # Opens NCG 
     [A-Za-z_]+   # Character class (any of the characters within) 
     \d*    # Token: \d (digit) 
     \.?    # Literal . 
    )+      # Closes NCG 
)       # Closes CG1 
\s?      # Token: \s (white space) 
\:       # Literal : 
(       # Opens CG2 
    [\s\S]+    # Character class (any of the characters within) 
)       # Closes CG2 
$       # Anchors to the end to the string. 

Теперь, вы можете захотеть изменить [\s\S]+ обратно .*, если вы имеете дело с несколькими линиями. Существует несколько различных вариантов, но это вопрос, какой язык вы используете.

Честно говоря, я сделал это пошагово, но самой большой проблемой было (?:.*)+ Это сообщение двигателю match 0 or more characters 1 or more timescatastrophic backtracking (as xufox linked to in comments).

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

Это будет соответствовать именам, например foo.ba5r, если это приемлемо, ваше предыдущее регулярное выражение не будет.

^([A-Za-z_]\w*(?:\.[A-Za-z_]+\w*)*)\s?\:([\s\S]+)$ 

Объяснение:

^      # Anchors to the beginning to the string. 
(       # Opens CG1 
    [A-Za-z_]    # Character class (any of the characters within) 
    \w*     # Token: \w (a-z, A-Z, 0-9, _) 
    (?:     # Opens NCG 
     \.     # Literal . 
     [A-Za-z_]   # Character class (any of the characters within) 
     \w*    # Token: \w (a-z, A-Z, 0-9, _) 
    )*      # Closes NCG 
)       # Closes CG1 
\s?      # Token: \s (white space) 
\:       # Literal : 
(       # Opens CG2 
    [\s\S]+    # Character class (any of the characters within) 
)       # Closes CG2 
$       # Anchors to the end to the string. 
+1

Если '\ .' находится в группе с квантором' + ', это не соответствует' foo: bar'. – Xufox

+0

@Xufox Действительно, typo (и я бы не поймал его, я был уверен, что использовал звездочку. Спасибо. Исправится) (изменить: исправлено) –

+0

Как насчет 'foo3_test: bar'? Не будет соответствовать, к сожалению ... – Xufox

Смежные вопросы