|
Регулярное выражение. Прошу помощи | ☑ | ||
---|---|---|---|---|
0
oleg_km
09.01.12
✎
12:43
|
Нужна конкретная помощь. Мало практики, никак не могу понять.
Есть строка: realm="1C-AGP", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41", algorithm=MD5, stale=false Нужно превратить в массив, в соответствии с запятыми, но игнорировать запятые, экранированные кавычками. Решал аналогичную проблему, но не смог и обошел, сейчас не могу обойти. |
|||
1
Kreont
09.01.12
✎
12:43
|
||||
2
oleg_km
09.01.12
✎
12:50
|
(1)
Спасибо, но не глубоко вникая в твой код не смог понять, как он будет игнорировать запятые в кавычках. Мне нужен такой результат: realm="1C-AGP" qop="auth,auth-int" nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093" opaque="5ccc069c403ebaf9f0171e9517f40e41" algorithm=MD5 stale=false А у тебя получится: realm="1C-AGP" qop="auth <-------- улавливаешь разницу auth-int" nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093" opaque="5ccc069c403ebaf9f0171e9517f40e41" algorithm=MD5 stale=false |
|||
3
Kreont
09.01.12
✎
12:54
|
А ну да тут ведь csv не по стандарту:(
Хотя замени сначала в исх.строке: ", " на "#@%BLA!" и используй как разделитель |
|||
4
KUBIK
09.01.12
✎
12:57
|
замени запятую на символ, которого заведомо никогда не должно быть в твоих значениях, обработай csv, затем обратно.
|
|||
5
oleg_km
09.01.12
✎
12:58
|
(3)
Извини, Василий, но опять мимо. Есть запятая, которая находится в тексте внутри кавычек: ="auth,auth-int". Она то и не является разделетелем. То есть разделители, это только запятые вне закавыченного текста. Это задачка как раз для регулярных выражений, но я пока в них не могу въехать |
|||
6
Живой Ископаемый
09.01.12
✎
13:01
|
Дополнение:
функция, которая правильно раскладывает строки типа вида: 20100912; 17.19;"Назначение платежа; которое не нужно делить на подстроки" То есть на три подстроки а не четыре: RegExp = Новый COMОбъект("VBScript.RegExp"); Результат = Новый Массив(); RegExp.IgnoreCase = Ложь; //Игнорировать регистр RegExp.Global = Истина; //Поиск всех вхождений шаблона RegExp.MultiLine = Ложь; //Многострочный режим RegExp.Pattern = "(?:^|;)(\""(?:[^\""]+|\""\"")*\""|[^;]*)"; //вот наш супер шаблон //RegExp.Pattern = ";|;|;|;|;;|;|;|;|;|;|;|;|;;|;|;"; //вот наш супер шаблон Matches=RegExp.Execute(Стр); ЧислоВхождений=Matches.Count(); //Сообщить(Стр,СтатусСообщения.Важное); Если ЧислоВхождений>0 Тогда Для к = 0 По ЧислоВхождений-1 Цикл Match = Matches.Item(к); SubMatches = Match.SubMatches; ЧислоПодвыражений=SubMatches.Count(); Для н = 0 По ЧислоПодвыражений-1 Цикл SubMatch=SubMatches.Item(н); Если SubMatch="" Тогда //Продолжить; КонецЕсли; Результат.Добавить(SubMatch); //Сообщить("Подстрока: "+SubMatch); КонецЦикла; КонецЦикла; Иначе //Сообщить("Вхождений шаблона не найдено"); КонецЕсли; Возврат Результат; |
|||
7
Kreont
09.01.12
✎
13:01
|
(5) см. (4)+(3)
П.С. У меня в (3) текст такой: "запятаяпробел" = ", " |
|||
8
Живой Ископаемый
09.01.12
✎
13:02
|
только вот тут:
RegExp.Pattern = "(?:^|;)(\""(?:[^\""]+|\""\"")*\""|[^;]*)"; //вот наш супер шаблон вместо точек с запятой - запятая |
|||
9
aleks-id
09.01.12
✎
13:07
|
массивстрок = стрзаменить(realm,", ",символы.пс);
|
|||
10
Живой Ископаемый
09.01.12
✎
13:09
|
2(9) ты ведь прочитал (2), верно?
|
|||
11
aleks-id
09.01.12
✎
13:11
|
(10) а ты ведь внимательно посмотрел, что у него разделитель строк - запятая плюс пробел да?
|
|||
12
Живой Ископаемый
09.01.12
✎
13:12
|
2(11) это частность - у него в строке может быть запятая и пробел и все...
|
|||
13
Живой Ископаемый
09.01.12
✎
13:12
|
realm="1C-AGP", qop="auth, auth-int"
|
|||
14
aleks-id
09.01.12
✎
13:12
|
(12) давай не будем за него телепатить ок? ;)
|
|||
15
Живой Ископаемый
09.01.12
✎
13:15
|
2(14) давай.. может конечно ты и прав, но тогда твой вариант предполагает что автор идиот, который проглядел такой простой вариант.. я так с людьми не могу, уж извини... предпочитаю думать что он просто привел не самый характерный пример строки, но объяснил именно то что ему нужно, а это решается простым паттерном из (8)
|
|||
16
oleg_km
09.01.12
✎
13:16
|
(14)
Нечего телепатить, все написано. "Живой Ископаемый" все правильно понял. (8) Твой пример с ; работает, заменяю на , - не хочет. Может , какой-то спецсимвол в RegExp'ах |
|||
17
aleks-id
09.01.12
✎
13:16
|
+(14) и даже если это так - все сводится к 3 строчкам:
массивстрок = стрзаменить(НашаСтрока,""",","@@##$$"); массивстрок = стрзаменить(массивстрок,",",символы.пс); массивстрок = стрзаменить(массивстрок,"@@##$$",""","); |
|||
18
Живой Ископаемый
09.01.12
✎
13:18
|
2(16) тогда фигово... я не большой знаток регэкспа.. но то что помню - когда я его нашел, он изначально был для запятой...
|
|||
19
aleks-id
09.01.12
✎
13:19
|
тьфу. неправильно в (17)
|
|||
20
Живой Ископаемый
09.01.12
✎
13:19
|
||||
21
Живой Ископаемый
09.01.12
✎
13:20
|
"^(("(?:[^"]|"")*"|[^,]*)(,("(?:[^"]|"")*"|[^,]*))*)$"
"(?:^|,)(\\\"(?:[^\\\"]+|\\\"\\\")*\\\"|[^,]*)" |
|||
22
Kreont
09.01.12
✎
13:20
|
(2) Я так понял не проверял готовой обработкой даже из (1)?
У меня для данной строки все сработало нормально. проверь. |
|||
23
Живой Ископаемый
09.01.12
✎
13:21
|
http://www.java2s.com/Code/Java/Development-Class/SimpledemoofCSVmatchingusingRegularExpressions.htm
"\"([^\"]+?)\",?|([^,]+),?|," |
|||
24
Живой Ископаемый
09.01.12
✎
13:22
|
но только кавычки внутри нужно удвоить
|
|||
25
oleg_km
09.01.12
✎
13:27
|
(20)
Не работает вообще, там товарищ внизу написал: Couldn't get this to work in .net :( (23) Почему-то ненужный разделитель все равно использует. Буду рыть дальше. Спасибо за участие |
|||
26
Живой Ископаемый
09.01.12
✎
13:28
|
потом только опубликуй годный шаблон как найдешь. :)
|
|||
27
Steel_Wheel
09.01.12
✎
13:35
|
||||
28
oleg_km
09.01.12
✎
13:39
|
(26)
Твой вариант тоже не работает, если исходную строку изменить на: 20100912; 17.19; Что-то "Назначение платежа; которое не нужно делить на подстроки" Так что это не совсем CSV |
|||
29
Живой Ископаемый
09.01.12
✎
13:48
|
2(28) стопроцентов работает.. сейчас
|
|||
30
oleg_km
09.01.12
✎
13:54
|
(29)
Только что пробовал, бъет внутри кавычек тоже |
|||
31
oleg_km
09.01.12
✎
13:58
|
Пока универсального шаблона опять не получилось. Получился более менее подходящий для данной задачи:
([a-z]*)=(?:([\'"])([^\2]+?)\2|([^\s,]+)) - взято из исходников PHP |
|||
32
Живой Ископаемый
09.01.12
✎
14:00
|
||||
33
oleg_km
09.01.12
✎
14:03
|
(32)
между ; и " вставь символы, на моей строке попробуй: 20100912; 17.19; Что-то "Назначение платежа; которое не нужно делить на подстроки" |
|||
34
Живой Ископаемый
09.01.12
✎
14:05
|
а понятно
|
|||
35
del123
15.01.12
✎
13:09
|
А чем плох такой код?)
|
|||
36
Torquader
15.01.12
✎
14:08
|
Ну - запятую в попу, а потом обычным парсером для командной строки - разобъёт на составляющие, а уже в них отрезать запятую с конца (если она там есть), а также разделить по знаку равно на переменную и её значение.
|
|||
37
Живой Ископаемый
15.01.12
✎
17:41
|
2(35) если работает, то всем хорош... Вообще код на чистом языке 1С предпочтительней, потому как не будет зависеть от среды исполнения - серверная она или клиентская, толстый или тонкий клиент, винда или линукс, какие права у пользователя под которым исполняется экземпляр программы и тому подобное...
Просто иногда почему-то интересно. |
|||
38
oleg_km
15.01.12
✎
20:12
|
(37) Разбор строки чистым кодом ну уровне сложных регулярных выражений - это практически всегда посимвольный разбор строки. А это средствами 1С очень медленно. Я сравнивал функцию-инициализатор строки (просто создает строку символов заданной длины) реализация на 1С уступает реализации на C++ в 1000 раз. А если нужно обработать текствый файл мегабайты? Просто хотелось одолеть китайскую грамоту регулярных выражений, все таки получается код всего четыре строчки, а не целый экран. Ладно, как-нибудь освоим
|
|||
39
Живой Ископаемый
15.01.12
✎
20:14
|
2(38) ну да, если ты уверен в каких условиях будет выполняться код и нужно чтобы он исполнялся быстро, тогда любые средства хороши...
|
|||
40
Simod
16.01.12
✎
07:29
|
Как-то так:
т_Текст = СоздатьОбъект("Текст"); сз_Список = СоздатьОбъект("СписокЗначений"); п_РС = РазделительСтрок; т_Текст.Открыть("C:\test.txt"); // файл со стороками Для п_НомерСтроки = 1 По т_Текст.КоличествоСтрок() Цикл п_Строка = СтрЗаменить(т_Текст.ПолучитьСтроку(п_НомерСтроки), "=", п_РС); п_Значение = СтрПолучитьСтроку(п_Строка, 1) + "="; Для п_НомерПозиции = 2 По (СтрКоличествоСтрок(п_Строка) - 1) Цикл п_Пункт = СтрЗаменить(СтрПолучитьСтроку(п_Строка, п_НомерПозиции), ",", п_РС); Для п_НомерПункта = 1 По (СтрКоличествоСтрок(п_Пункт) - 1) Цикл п_Значение = п_Значение + СтрПолучитьСтроку(п_Пункт, п_НомерПункта) + ","; КонецЦикла; сз_Список.ДобавитьЗначение(Лев(п_Значение, СтрДлина(п_Значение) - 1)); п_Значение = СокрЛП(СтрПолучитьСтроку(п_Пункт, СтрКоличествоСтрок(п_Пункт))) + "="; КонецЦикла; сз_Список.ДобавитьЗначение(п_Значение + СтрПолучитьСтроку(п_Строка, СтрКоличествоСтрок(п_Строка))); КонецЦикла; сз_Список.ВыбратьЗначение(,,,, 0); |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |