Как редактировать «Регулярное выражение полного пути к папке Windows» - PullRequest
1 голос
/ 12 июля 2010

Hay это регулярное выражение работает нормально для Полный путь к папке Windows

^([A-Za-z]:|\\{2}([-\w]+|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\\(([^"*/:?|<>\\,;[\]+=.\x00-\x20]|\.[.\x20]*[^"*/:?|<>\\,;[\]+=.\x00-\x20])([^"*/:?|<>\\,;[\]+=\x00-\x1F]*[^"*/:?|<>\\,;[\]+=\x00-\x20])?))\\([^"*/:?|<>\\.\x00-\x20]([^"*/:?|<>\\\x00-\x1F]*[^"*/:?|<>\\.\x00-\x20])?\\)*$

Совпадения
d:\, \\Dpk\T c\, E:\reference\h101\, \\be\projects$\Wield\Rff\, \\70.60.44.88\T d\SPC2\

Несоответствия
j:ohn\, \\Dpk\, G:\GD, \\cae\.. ..\, \\70.60.44\T d\SPC2\

ПРОБЛЕМА: ЭТОТ ВЫРАЖЕНИЕ ТРЕБУЕТСЯ "\" КОНЕЦ ПУТИ.КАК Я МОГУ РЕДАКТИРОВАТЬ ЭТОТ ВЫРАЖЕНИЕ, ЧТОБЫ ПОЛЬЗОВАТЕЛЬ МОЖЕТ ВХОДИТЬ В ПУТЬ, КАК C:\Folder1, C:\Folder 1\Sub Folder

Ответы [ 4 ]

5 голосов
/ 12 июля 2010

Существует два способа решения этой проблемы:

  • Понять регулярное выражение (намного сложнее, чем необходимо) и исправить его в соответствии с вашими требованиями (возможно, с ошибками)
  • Кому интересно, как регулярное выражение делает свое дело (кажется, оно делает то, что вам нужно) и изменяет ваш вклад, чтобы соответствовать тому, что вы думаете, регулярное выражение делает

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

Обычно я бы не рекомендовал эту невежественную альтернативу, но это может быть исключением.


Blackboxing

Вот как я «решаю» эту проблему:

  • Есть волшебная коробка, которая знает, как она работает, но работает 99% времени
  • Мы хотим, чтобы это работало 100% времени
  • Проще исправить 1%, чтобы он работал с волшебной коробкой, а не исправлять саму волшебную коробку (потому что это потребовало бы понимания того, как работает волшебная коробка)
  • Тогда просто исправьте 1% вручную и оставьте волшебную коробку в покое

Расшифровка чёрной магии

Тем не менее, мы, конечно, можем попытаться взглянуть на регулярное выражение. Вот тот же шаблон, но переформатированный в режиме свободного пробела / комментария, т.е. (?x), например. Java.

^
( [A-Za-z]:
| \\{2}   ( [-\w]+
          | (
               (25[0-5]
               |2[0-4][0-9]
               |[01]?[0-9][0-9]?
               )\.
            ){3}
               (25[0-5]
               |2[0-4][0-9]
               |[01]?[0-9][0-9]?
               )
          )
  \\ (
       (    [^"*/:?|<>\\,;[\]+=.\x00-\x20]
       |  \.[.\x20]* [^"*/:?|<>\\,;[\]+=.\x00-\x20]
       )
       (    [^"*/:?|<>\\,;[\]+=\x00-\x1F]*
            [^"*/:?|<>\\,;[\]+=\x00-\x20]
       )?
     )
)
\\ ( 
         [^"*/:?|<>\\.\x00-\x20]
      (
         [^"*/:?|<>\\\x00-\x1F]*
         [^"*/:?|<>\\.\x00-\x20]
      )?
      \\
   )*
$

Основной каркас шаблона выглядит следующим образом:

^
(head)
\\ (
      bodypart
      \\
   )*
$

Исходя из этого высокоуровневого представления, похоже, что дополнительный трейлинг \ может быть поддержан путем добавления ? к двум \\ после части (head):

^
(head)
\\?(
      bodypart
      \\?
   )*
$

Ссылки


Примечание о катастрофическом возврате

Как правило, вы должны очень опасаться вложенных модификаторов повторения (в данном случае ? внутри *), но для этого конкретного шаблона это "хорошо", потому что bodypart не не соответствует \.

Ссылки

1 голос
/ 05 января 2011

Заданное вами регулярное выражение, похоже, не соответствует "C: \? Tmp", что является неверным путем к Windows.

Я нашел одно решение, но оно работает только в Windows.Вы можете попробовать это:

"^[A-Za-z]:(?:\\\\(?![\"*/:?|<>\\\\,;[\\]+=.\\x00-\\x20])[^\"*/:?|<>\\\\[\\]]+){0,}(?:\\\\)?$"

Это регулярное выражение игнорирует последний "\", который вам мешает.

Я тестировал с pcre.lib (5.5) в VS2005.

Надеюсь, это поможет!

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

Я не понимаю ваше регулярное выражение вообще . Но я держу пари, что все, что вам нужно сделать, это найти биты или биты, которые соответствуют конечному «\», и ​​добавить один знак вопроса после этого бита или этих битов.

0 голосов
/ 09 мая 2014

Я знаю, что этому вопросу примерно 4 года, но следующего может быть достаточно:

string validWindowsOrUncPath = @"^(?:(?:[a-z]:)|(?:\\\\[^\\*\?\:;\0]*))(?:\\[^\\*\?\:;\0]*)+$";

(для использования с опцией IgnoreCase).

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

string validWindowsOrUncPath = @"^(?<Root>(?:[a-z]:)|(?:\\\\[^\\*\?\:;\0]*))(?:\\(?<Part>[^\\*\?\:;\0]*))+$";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...