Marc A. Brown Ответов: 2

Регулярное выражение для разбиения строки, разделенной запятыми


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

Вот регулярное выражение:
string sToken = @"(?:,\s+)|(['""].+['""])(?:,\s+)";

Вот пример строки:
var s = "1.3#, 2.99, 3\t, 4#2/2/1019#, 5, asd,, 'Howdy, Howdy, Howdy', a;sdlkf";

Результаты:
1.3#
2.99
3\t
4#2/2/1019#
5
asd,

'Howdy, Howdy, Howdy'
a;sdlkf

The blank line between "asd," and "'Howdy, Howdy, Howdy" is the issue. I believe I understand why it's showing up, but I don't know what regex magic I need to do to prevent it. I believe it's showing up because the regex processor finds the ", " after "asd," and splits "asd," out. It then finds another match (the "'Howdy, Howdy, Howdy'") and splits out everything between the ", " and the "'Howdy, Howdy, Howdy'" (and empty string). Note that the two commas after "asd" are not the problem. Removing one of them provides the same results except that "asd," becomes "asd" (as expected). Putting a space between the commas gives us "asd" followed by two blank lines instead of one.

Я большой любитель в мире регулярных выражений, но мой босс пришел ко мне, потому что ему сказали, что я могу что-то знать о них (Визгун, который сказал ему это, был соответствующим образом наказан). :)

В любом случае, я был бы признателен за любую помощь в решении этой проблемы.

Чтобы прояснить, что мы ищем в качестве вывода, было бы следующим:
необходимые результаты:
1.3#
2.99
3\t
4#2/2/1019#
5
asd,
'Howdy, Howdy, Howdy'
a;sdlkf


В "'привет, Привет, Привет" будет одна запись, без пустой строки. Если, Однако, наш образец выглядел так (Обратите внимание на пробел между двумя запятыми после "asd"):
var s = "1.3#, 2.99, 3\t, 4#2/2/1019#, 5, asd, , 'Howdy, Howdy, Howdy', a;sdlkf";

необходимые результаты:
1.3#
2.99
3\t
4#2/2/1019#
5
asd

'Howdy, Howdy, Howdy'
a;sdlkf

(обратите внимание на пустую строку, представляющую пустое значение между двумя запятыми, и отсутствие запятой в конце "asd")

Richard C Bishop

Вам обязательно использовать REG EX?

Marc A. Brown

Ну, это не мой проект, так что я не знаю, есть ли требование использовать регулярное выражение или нет. Если у вас есть альтернативное предложение, пожалуйста, не стесняйтесь предложить его. Тем не менее, даже если босс решит пойти другим путем, я надеюсь, что кто-то сможет указать на решение регулярных выражений, чтобы улучшить мое понимание. :)

[no name]

Описание вопроса кажется мне немного неполным. Вы хотите, чтобы это было "Привет, Привет, Привет" или
- Привет
Привет
Как дела ? Также вы хотите, чтобы это было как 3\t или только 3?

Marc A. Brown

Спасибо, что ответили. Вы правы-я должен был обеспечить желаемые результаты. Я обновил вопрос.

[no name]

Удалил свое решение, так как я не мог понять его раньше, дайте мне посмотреть, смогу ли я придумать лучшее решение. :)

Marc A. Brown

Большое спасибо.

2 Ответов

Рейтинг:
9

André Kraak

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

Используя это выражение, я получил результат без дополнительной пустой строки, которую вы ищете.

,\s+(?=(?:(?:[^']*'){2})*[^']*$)

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


Marc A. Brown

Блестяще! Большое спасибо!

Рейтинг:
2

Pallavi Waikar

Попробуйте linq с примером регулярного выражения

string s = @"1.3#, 2.99, 3\t, 4#2/2/1019#, 5, asd,, 'Howdy, Howdy, Howdy', a;sdlkf";
string[] myValues = Regex.Split(s, @"(?:,\s+)|(['""].+['""])(?:,\s+)").Where(s2 => !string.IsNullOrEmpty(s2)).ToArray();
foreach (string s1 in myValues)
    MessageBox.Show(s1);


Marc A. Brown

Хороший ответ, но он будет устранять пустые значения *слишком* агрессивно. Например, если бы между двумя запятыми после "asd" был пробел, регулярное выражение в его нынешнем виде дало бы нам пустую строку, которую мы хотели бы сохранить, в дополнение к той, которой там не должно быть. Но мне нравится это предложение. Спасибо!