Синтаксический анализ цитируемых путей в C # из командной строки и предотвращение Escape-символов - PullRequest
22 голосов
/ 23 мая 2009

Как можно проанализировать аргументы командной строки, которые должны интерпретироваться как пути? args [] содержит строки, которые автоматически объединяются, если они заключены в кавычки, например ::

example.exe один два "три четыре"

args[0] = one
args[1] = two
args[2] = three four

Однако args [] не будет анализировать свойство "C: \ Example \" в качестве аргумента. Скорее, он предоставит аргумент как «C: \ Example» »(с добавлением дополнительной кавычки.) Это происходит из-за обратной косой черты в пути, которая обрабатывается как escape-символ, и, таким образом, конечной кавычки, которую пользователь указал в команде. -линия становится частью аргумента.

.e.g:

example.exe one "C: \ InputFolder" "C: \ OutuptFolder \"

args[0] = one
args[1] = C:\InputFolder"
args[2] = C:\OutputFolder"

Легким клуджем может быть:

_path = args[i].Replace("\"", @"\");

Однако я уверен, что для этого есть лучшая практика. Как можно правильно проанализировать командную строку, которая включает пути, предотвращая неправильное заполнение массива args [] строками, которые были проанализированы для escape-символов?

ПРИМЕЧАНИЕ. Я не хотел бы включать в свой проект целую библиотеку синтаксического анализа командной строки! Мне нужно работать только с указанными путями, и я хочу сделать это «вручную». Пожалуйста, не рекомендуется использовать NConsoler, Mono или любую другую большую библиотеку синтаксического анализа командной строки «кухонная раковина».

ТАКЖЕ ПРИМЕЧАНИЕ: Насколько я могу судить, это не повторяющийся вопрос. В то время как другие вопросы сосредоточены на общем синтаксическом анализе командной строки, этот вопрос относится к проблеме, которая возникает в путях, когда их части интерпретируются как escape-последовательности.

Ответы [ 3 ]

9 голосов
/ 23 мая 2009

Не ответ, но вот некоторые справочная информация и объяснение от Джеффри Тана, Microsoft Online Community Support (12/7/2006):

Примечание: это не поражение кода но по замыслу, так как обратная косая черта обычно используется, чтобы избежать определенных особый персонаж. Кроме того, это алгоритм такой же, как команда Win32 функция разбора аргументов строки CommandLineToArgvW. Смотрите замечания раздел ниже: http://msdn2.microsoft.com/en-us/library/bb776391.aspx

Также ссылается на метод FX Environment.GetCommandLineArgs для дальнейшего объяснения поведения обработки косой черты.

Лично я считаю, что это тормоз, и я удивлен, что раньше меня это не беспокоило. А может я и не знаю? Слепая замена цитат косыми чертами не кажется мне решением проблемы. Я поднимаю вопрос, потому что это было откровением.

1 голос
/ 07 сентября 2009

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

// Capture quoted string or non-quoted strings followed by whitespace
string exp = @"^(?:""([^""]*)""\s*|([^""\s]+)\s*)+";
Match m = Regex.Match(Environment.CommandLine, exp);

// Expect three Groups
// group[0] = entire match
// group[1] = matches from left capturing group
// group[2] = matches from right capturing group
if (m.Groups.Count < 3)
    throw new ArgumentException("A minimum of 2 arguments are required for this program");

// Sort the captures by their original postion
var captures = m.Groups[1].Captures.Cast<Capture>().Concat(
               m.Groups[2].Captures.Cast<Capture>()).
               OrderBy(x => x.Index).
               ToArray();

// captures[0] is the executable file
if (captures.Length < 3)
    throw new ArgumentException("A minimum of 2 arguments are required for this program");

Может кто-нибудь увидеть более эффективное регулярное выражение?

1 голос
/ 23 мая 2009

Мне нравится твоя идея:

_path = args[i].Replace("\"", @"\");

Это чисто, и не будет иметь никакого эффекта, если проблема не существует.

...