Это нужно сделать:
string test = @"This|is|a|pip\|ed|test (this is a pip|ed test)";
string[] parts = Regex.Split(test, @"(?<!(?<!\\)*\\)\|");
Регулярное выражение в основном гласит: разделить на каналы, которым не предшествует escape-символ. Я не должен брать за это никакой заслуги, я просто похитил регулярное выражение из этого поста и упростил его.
EDIT
С точки зрения производительности, по сравнению с методом ручного синтаксического анализа, представленным в этой теме, я обнаружил, что эта реализация Regex в 3-5 раз медленнее, чем реализация Джонатона Вуда с использованием более длинной тестовой строки, предоставленной OP.
С учетом сказанного, если вы не создадите или не добавите слова в List<string>
и не вернете void, метод Джона будет работать примерно в 5 раз быстрее, чем метод Regex.Split()
(0,01 мс против 0,002 мс) для чистого разделения строки. Если вы добавите обратно издержки на управление и возврат List<string>
, он будет примерно в 3,6 раза быстрее (0,01 мс против 0,00275 мс), усредненный по нескольким наборам по миллиону итераций. Я не использовал статический Regex.Split () для этого теста, вместо этого я создал новый экземпляр Regex с приведенным выше выражением вне моего цикла тестирования, а затем вызвал его метод Split.
UPDATE
Использование статической функции Regex.Split () на самом деле намного быстрее, чем повторное использование экземпляра выражения. В этой реализации использование регулярных выражений только примерно в 1,6 раза медленнее, чем реализация Джона (0,0043 мс против 0,00275 мс)
Результаты были такими же, используя расширенное регулярное выражение из поста, на который я ссылался.