Разделить строку каждый раз, когда детерминированные конечные автоматы достигают конечного состояния?

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

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

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

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

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

альтернативный текст

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


person Alain    schedule 16.12.2010    source источник


Ответы (2)


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

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

Вы можете расширить вышеизложенное до этого: ^(?:(?:"(?<Value>[^"]*)")|(?<Value>[^,]*))(?:,(?:(?:"(?<Value>[^"]*)")|(?<Value>[^,]*)))*$

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

person Mr. TA    schedule 16.12.2010
comment
Я нахожусь в VBA для этого, я думаю, поэтому мне придется прибегнуть к синтаксису VBScript. К счастью для меня, я считаю, что они очень похожи (хотя реализация VBScript не поддерживает возможности просмотра позади .Net). Я не могу дождаться, чтобы проверить это, спасибо! - person Alain; 16.12.2010

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

",(?=(?:[^""]*""[^""]*"")*[^""]*$)"
person Alan Moore    schedule 17.12.2010