Regex блокирует программу - PullRequest
2 голосов
/ 11 мая 2010

У меня есть следующее регулярное выражение

Dim origen As String = "  /c /p:""c:\mis doc umentos\mis imagenes construida\archivo.txt"" /cid:45    423 /z:65 /a:23  /m:39 /t:45rt "

Dim str As String = "(^|\s)/p:""\w:(\\(\w+[\s]*\w+)+)+\\\w+.\w+""(\s|$)"
Dim ar As Integer

Dim getfile As New Regex(str)
Dim mgetfile As MatchCollection = getfile.Matches(origen)
ar = mgetfile.Count

Когда я оцениваю это, оно работает и получает /p:""c:\mis doc umentos\mis imagenes construida\archivo.txt"", который в основном является путем к файлу.

Но если я изменю исходную строку на

Dim origen As String = "  /c /p:""c:\mis doc umentos\mis imagenes construida\archivo.txt""/cid:45    423 /z:65 /a:23  /m:39 /t:45rt "

Убедитесь, что за концом файла следует "/ cid: 45", что делает де-шаблон недействительным, но вместо получения mgetfile.count = 0 программа блокируется, если я отлаживаю, я получаю оценка свойства не удалась.

Ответы [ 3 ]

2 голосов
/ 12 мая 2010

Можете ли вы очистить все выражение до:

str = "/p:"".*?"""
1 голос
/ 12 мая 2010

Причина, по которой ваша программа зависает, - катастрофический возврат .

Части вашего регулярного выражения (\w+\s*\w+)+ и \w+.\w+ допускают так много перестановок, что механизм регулярных выражений застревает в почти бесконечном цикле. Отладчик RegexBuddy завершает работу после 1000000 шагов.

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

Каковы реальные требования? Чтобы соответствовать пути, который содержит только буквы, цифры, подчеркивания и обратные слеши? Или просто строка между кавычками? Возможно, вы могли бы пролить свет на это ...

До этого я предлагаю следующее:

"(?<=^|\s)/p:""\w:(\\[\w\s]++)+\.\w+""(?=\s|$)"

Это очищает несколько вещей: (\\[\w\s]++) соответствует обратной косой черте, за которой следует любое количество буквенно-цифровых и пробельных символов. Как только они сопоставлены, механизм регулярных выражений отказывается пробовать другую перестановку (это достигается с помощью возможного квантификатора ++ вместо просто +.

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

Если вы хотите сопоставить строку между кавычками, тогда

"(?<=^|\s)/p:""[^""]+""(?=\s|$)"

самый лучший и быстрый способ.

0 голосов
/ 12 мая 2010

Вы всегда знаете, что в начале и конце есть две двойные кавычки? Если это так, просто сделайте:

(^|\s)/p:""(.*?)""(.*$)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...