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

Например, из строки if(a>b) write(a); я хочу получить if, (, a, >, b, ) , write, (, a, ), ;

Вот что я пробовал:

string pattern = "(" + String.Join("|", delimiters.Select(d =>Regex.Escape(d)).ToList()) + ")";
List<string> result = Regex.Split(line, pattern).ToList();

Это работает, но в некоторых случаях не работает. Если бы у меня была строка if(a>0) write("it is positive");, я бы не хотел получить "it, is, positive" (потому что пробел является разделителем), а "it is positive". Как я могу это сделать?

3
user1012732 22 Окт 2015 в 12:56

2 ответа

Лучший ответ

Соответствие строк C может быть достигнуто с помощью известного регулярного выражения:

"[^"\\]*(?:\\.[^"\\]*)*"

См. демонстрация регулярного выражения

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

var delimiters = new List<string> { " ", "(", ")", ">", "<", ",", ";"};
var line = "if(a>b) write(\"My new result\")";
var escaped_delimiters = new List<string>();
escaped_delimiters.Add(@"""[^""\\]*(?:\\.[^""\\]*)*""");
escaped_delimiters.AddRange(delimiters.Select(d => Regex.Escape(d)).ToList());
var pattern = "(" + String.Join("|", escaped_delimiters) + ")";
var result = Regex.Split(line, pattern).Where(x => !String.IsNullOrWhiteSpace(x)).ToList();

См. демонстрацию IDEONE

Если вам не нужны пустые элементы, используйте

List<string> result = Regex.Split(line, pattern).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();

Результат будет

enter image description here

2
Wiktor Stribiżew 22 Окт 2015 в 10:33

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

@"(?:""[^""]*""|\w|[^\w\s])+"
1
Avinash Raj 22 Окт 2015 в 09:59