Имя: Пароль:
1C
1С v8
Для овладевших регулярными выражениями
, ,
0 Fragster
 
гуру
15.04.15
18:14
нужно из строки выделить фрагменты вида {туттекст}. трудность в том, что в скобках нужно игнорировать } и {, а также \.

аа{аа}аа       -> {аа}
аа{аа}аа}а     -> {аа}
аа{аа}аа}а    -> {аа}аа}
аа{аа\}aа}aaa -> {аа\}


вот такой шаблон: {((\\)|(\})|(\{)|([^{}]))*} хрет всё, кроме последнего.
больше тестовых примеров накидаю после того, как с этим будет ОК
1 Fragster
 
гуру
15.04.15
18:17
миста сожрала нужные "\" :(
2 Fragster
 
гуру
15.04.15
18:19
как-то так: http://pastebin.com/4Pvp4PkM
3 Fragster
 
гуру
15.04.15
18:20
хотя что-то я уже загнался, вроде {((\\)|(\})|(\{)|([^{}]))*} как раз работает
4 Fragster
 
гуру
15.04.15
18:21
все "\" надо превратить в "\" а Asmody посмотреть, почему миста их жрет
5 Гёдза
 
15.04.15
18:25
по твоим примерам как раз не нужно игрнорировать в скобках. до первой скобки закрывающей
6 Fragster
 
гуру
15.04.15
18:33
(5) миста сожрала \
7 Jaap Vduul
 
15.04.15
19:13
(3)Какой-то перекрученый паттерн.
Если нужен текст между первой и последней фигурными скобками в строке, то достаточно "(\{.*\})".
8 Fragster
 
гуру
15.04.15
22:34
(7) нужен текст между последней открывающей, у которой есть парная закрывающая, а также нужно учесть экранирование с помощью \
9 sda553
 
16.04.15
01:02
(2) логика 4-го выражения как то противоречит логике второго, а так я бы взял выражение
/\{(.*[^\\])}/
10 Fragster
 
гуру
16.04.15
10:18
(9) короче, нужно найти самую вложенную пару скобок, слеш} и слеш{ скобками не считаются. слешслеш не считается слеш
11 Fragster
 
гуру
16.04.15
10:19
короче слеш - это символ экранирования. экранируются слеш, } и {
12 Fragster
 
гуру
16.04.15
20:22
если кому интересно - это был шаблонизатор. в итоге забил, сделал на XPATH:

http://snag.gy/JlMpe.jpg
13 Fragster
 
гуру
16.04.15
20:31
и даже так: http://snag.gy/C7fC0.jpg
14 Ma3eIIa
 
16.04.15
20:47
аа{аа}аа}а     -> {аа}
аа{аа}аа}а    -> {аа}аа}
аа{аа\}aа}aaa -> {аа\}


почему во втором берем аа} а в 3 игнорируем ?
15 Fragster
 
гуру
16.04.15
21:02
(14) потому что миста сожрала много символов "\". вот тут видно: http://pastebin.com/4Pvp4PkM

типа один обратный слеш экранирует следующий символ.
16 Ma3eIIa
 
16.04.15
21:19
ВЫБРАТЬ
    "{aa}" КАК Поле1
ПОМЕСТИТЬ vt

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "aa{aa}aa"
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    vt.Поле1
ИЗ
    vt КАК vt
ГДЕ
    vt.Поле1 ПОДОБНО "{%%}"
17 Ma3eIIa
 
16.04.15
21:22
(1) не то
18 Ma3eIIa
 
16.04.15
21:45
тока RegExp в скрипте. а в 1с много кода...
19 Fragster
 
гуру
16.04.15
22:53
(18) я не понял, что ты имеешь ввиду, но RegExp в 1с можно юзать через ком объект http://infostart.ru/public/75941/
20 Asmody
 
16.04.15
23:09
(0) нафиг регулярки, напиши синтаксический анализатор
21 Fragster
 
гуру
16.04.15
23:10
(20) на 1с строковые функции унылы. ну да сделал уже поменяв язык шаблонов и разрулив через XPATH -> (12)(13)
22 По-читатель
 
16.04.15
23:11
(0) {.+\\{3}.+?}|{.+\w\\}.+?}|{.+?}
23 Fragster
 
гуру
16.04.15
23:13
(22) ну как бы в (0) предполагается, что заэкранированных скобок внутри может быть сколько угодно, в том числе 0, ну и в любом порядке
24 Asmody
 
16.04.15
23:37
(21) Да это ж несложно http://infostart.ru/public/316338/
25 sda553
 
17.04.15
09:55
(10) тогда это обычный нон-гриди поиск с таким выражением
[^\\](\{.*?[^\\]})
26 sda553
 
17.04.15
10:19
(25) прогнал. Вот окончательный вариант, прошедший все твои тестовые примеры из (15)
[^\\]?(\{(?:[\\]?.)*?})

Описание:
Ищется выражение начинающееся с символа {, перед которым не должно быть символа \.
после { идут несколько(более или равно нулю) групп из одного любого символа, или '\'+один символ. выражение заканчивается символом }
27 Fragster
 
гуру
17.04.15
10:27
(26) из\{аа\} должно получиться {aa\}. я ж говорю - слеш экранирует следующий символ, в т.ч. сам слеш
28 Fragster
 
гуру
17.04.15
10:27
в (27) \ надо заменить на \ \
29 Fragster
 
гуру
17.04.15
10:28
без пробела
30 sda553
 
17.04.15
12:01
(27) я просто не думал, что экраны за пределами {} то же волнуют, тогда надо вообще с начала строки анализировать, чтобы если что посчитать - четное там количество экранов или нет. Получилось так:
^(?:[\\]?[^\\]|\\\\)*(\{(?:[\\]?[^\\]|\\\\)*?})
31 Jaap Vduul
 
17.04.15
12:21
(30)Такая регулярка захавает весь текст, ибо звёздочка в середине жадная.
(10)\{.*?([^\\]|[^\\]\\{2})\}
32 sda553
 
17.04.15
12:25
(31) не правильно, не зохавает
33 sda553
 
17.04.15
12:29
(31) твое выражение не правильно обрабатывает строку
ff{f\ff} => {f\ff}
а так же
ff\{ff{fff} => {fff}
34 sda553
 
17.04.15
13:54
(?:^|[^\\])(?:\\\\)*(\{(?:[\\]?[^\\]|\\\\)*?})
такое выражение при флаге g захватит все самые внутренние {} в строке если их несколько
35 DEVIce
 
17.04.15
14:05
(20) Да, да, восходящим разбором, потом нисходящим и только потом СД. Извращаться так извращаться.
Независимо от того, куда вы едете — это в гору и против ветра!