Разделить строку, основываясь на том, что каждый детерминированный конечный автомат достигает конечного состояния? - PullRequest
2 голосов
/ 16 декабря 2010

У меня есть проблема, решение которой можно решить путем итерации, но мне интересно, есть ли более элегантное решение с использованием регулярных выражений и split()

У меня есть строка (которую Excel помещает в буфер обмена), которая, по сути, разделена запятой. Предостережение заключается в том, что когда значения ячеек содержат запятую, вся ячейка заключена в кавычки (предположительно, для экранирования запятых в этой строке). Пример строки выглядит следующим образом:

123,12,"12,345",834,54,"1,111","98,273","1,923,002",23,"1,243"

Теперь я хочу элегантно разделить эту строку на отдельные ячейки, но выгода заключается в том, что я не могу использовать нормальное выражение разбиения с запятой в качестве разделителя, поскольку оно будет делить ячейки, содержащие запятую в своем значении. Другой способ решения этой проблемы заключается в том, что я могу ТОЛЬКО разделить запятую, если перед запятой стоит ДАЖЕ число кавычек.

Это легко решить с помощью цикла, но мне интересно, есть ли функция регулярного выражения.сплит, способная захватить эту логику. В попытке решить эту проблему, я построил детерминированные конечные автоматы (DFA) для логики.

alt text

Теперь вопрос сводится к следующему: есть ли способ разбить эту строку таким образом, чтобы новый элемент массива (соответствующий / s) создавался каждый раз, когда в DFA достигается конечное состояние (состояние 4 здесь)?

Ответы [ 2 ]

0 голосов
/ 17 декабря 2010

Допустимые запятые также сопровождаются четным числом кавычек, а VBScript поддерживает поддержку просмотра. Попробуйте разделить на это:

",(?=(?:[^""]*""[^""]*"")*[^""]*$)"
0 голосов
/ 16 декабря 2010

Использование регулярного выражения (без отступа): (?:(?:"[^"]*")|(?:[^,]*))

Используйте это и вызовите Regex.Matches (), который является .NET или его аналогом на других платформах.

Вы могли бы расширить это до следующего: ^(?:(?:"(?<Value>[^"]*)")|(?<Value>[^,]*))(?:,(?:(?:"(?<Value>[^"]*)")|(?<Value>[^,]*)))*$

Это проанализирует всю строку за 1 выстрел, но для этого вам понадобятся именованные группы и множественный захват для каждой группы (.NET поддерживает это).

...