Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) regexp, ПолучитьТекстМодуля и пр. (число прочтений - 5298 )
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
regexp, ПолучитьТекстМодуля и пр.
13. Июня 2012 :: 08:37
Печать  
Есть такая задача:

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

Первое, если я правильно мыслю, делается с помощью ПолучитьТекстМодуля объекта Информатор. Т.е. делаю перебор всех объектов метаданных, создаю объект в цикле и передаю в ПолучитьТекстМодуля. Или другой вариант - разложить МД gcomp-ом и парсить файлы.

А второе решается с помощью регулярного выражения. Но пока у меня есть загвоздка.
Есть регулярное выражение:

"([^"\n]|"".)*?"

оно отлавливает (на JavaScript) весь текст в кавычках, включая экранирование кавычек, т.е. двойные "" внутри текста.
Например, в такой строке:
Код
Выбрать все
Если (СловоПоНомеру(Стр,1)="Функция ""+"" ")или(СловоПоНомеру(Стр,1)="Процедура")
 


Но вот если добавить условие получения двух символов в начале (по моим соображениям, всё, что не Я (или я), т.е. так:

[^яЯ]{2}"([^"\n]|"".)*?"

то регулярка начинает не правильно работать. И выделяет так:
Код
Выбрать все
Если (СловоПоНомеру(Стр,1)="Функция ""+"" ")или(СловоПоНомеру(Стр,1)="Процедура")
 


Т.е. потеряла в первом выделении пару символов.
Будут у кого-то соображения на этот счёт?

Кстати, проверять регулярные выражения удобно здесь: http://iblogbox.com/devtools/regexp/
« Последняя редакция: 13. Июня 2012 :: 09:45 - alyuev »  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #1 - 13. Июня 2012 :: 09:00
Печать  
alyuev писал(а) 13. Июня 2012 :: 08:37:
Например, в такой строке:
Код
Выбрать все
Если (СловоПоНомеру(Стр,1)="Функция ""+"" ")или(СловоПоНомеру(Стр,1)="Процедура")
 


Цитата:
Match Count: 4
не смущает?  Подмигивание
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #2 - 13. Июня 2012 :: 09:14
Печать  
Смущает, хотя у меня 3 получилось, а не 4.
Если добавить в первый набор исключение кавычки, т.е. [^Яя"]..., то будет 2 совпадения, но тоже не правильных:

Код
Выбрать все
Если (СловоПоНомеру(Стр,1)="Функция ""+"" ")или(СловоПоНомеру(Стр,1)="Процедура") 

  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #3 - 13. Июня 2012 :: 09:21
Печать  
3 - если флажок Global не стоит, но тогда выделение получается не такое, как у тебя в примере.
4:
"Функция "
"+"
" "
"Процедура"

т.е. твой шаблон строку не находит.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #4 - 13. Июня 2012 :: 09:42
Печать  
Попробуй убери знак ? в конце регулярного выражения (это если ты на VBScript тестируешь)
  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #5 - 13. Июня 2012 :: 09:55
Печать  
[^яЯ]\("([^"]|"".)*"

Круглые глаза
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #6 - 13. Июня 2012 :: 09:55
Печать  
О! Кажись разобрался:

Вот так:

[^Яя]{2}"([^"\n]|"")*"
  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #7 - 13. Июня 2012 :: 10:44
Печать  
Нет.... В такой строке это выражение не работает:

Код
Выбрать все
СообщитьвФайл(Я("Файл ")+ФайлВладелец+Я(" залочен (")+Лок+")","ВставкаЛистаExcel");Сообщить(Лок);
 



В общем, понятно почему. Первая кавычка не прошла условие, т.к. там Я( стоит. Зато найдена вторая кавычка, которая подходит по условию и с неё всё ломается...

Код
Выбрать все
СообщитьвФайл(Я("Файл ")+ФайлВладелец+Я(" залочен (")+Лок+")","ВставкаЛистаExcel");Сообщить(Лок);
 



а по идее должен был найти вот это:

Код
Выбрать все
СообщитьвФайл(Я("Файл ")+ФайлВладелец+Я(" залочен (")+Лок+")","ВставкаЛистаExcel");Сообщить(Лок);
 



  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #8 - 13. Июня 2012 :: 10:56
Печать  
Пока сделал такое выражение:

.{1,2}"([^"\n]|"")*"

оно выбирает текст в кавычках и 1 или 2 символа перед ним. Наверное, придется потом проверять эти символы на неравенство Я( уже после получения результата.
  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #9 - 13. Июня 2012 :: 11:14
Печать  
Если завернуть эти символы в скобки, их можно будет получить в коллекции Submatches:
Код
Выбрать все
Set RegEx = New RegExp
RegEx.Pattern = "(.{0,2})""([^""]|"""".)*"""
RegEx.Global = True

Text = "СообщитьвФайл(Я(""Файл "")+ФайлВладелец+Я("" залочен ("")+Лок+"")"",""ВставкаЛистаExcel"");Сообщить(Лок);"
Set Matches = RegEx.Execute(Text)
For Each Match In Matches
	WScript.Echo Match.Submatches(0)
Next
 

  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #10 - 13. Июня 2012 :: 12:31
Печать  
Ага. Так и сделал. И для текста в кавычках. Спасибо за участие!

Осталось за малым - модули повытаскивать Улыбка
  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #11 - 14. Июня 2012 :: 12:30
Печать  
Уточняю выражение:

(?:^|[^"\n]{0,2})("([^"\n]|"")*") - вытаскивает все, что в кавычках (включая кавычки) и до двух символов перед первой кавычкой, чтобы в дальнейшем проверить эти возможные два символа на совпадение с Я(.
  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #12 - 14. Июня 2012 :: 12:44
Печать  
Да..... Задачка получилась непростая...

В общем и целом регулярка выше находит всё правильно. Но с её помощью я могу попасть на лишнюю строку, если аргумент функции Я составной, т.е. типа Я("трата"+Перем+"тамтам"). И т.к. я хочу автоматом обрамить строку в Я(), то первое выделение не пройдет условие, т.к. она уже в Я(, а второе выделение поймается и пройдет условие, т.к. первые 2 симв. не Я(, хотя эта строка входит в аргумент.

Попытался решить задачу с другой стороны - вычленить функцию Я() со всем её содержимым. Но, по всей видимости, задача не решится с помощью регулярных выражений.

Как пример (в качестве зарядки для ума Улыбка ), попробуйте вычленить выделенное в строке:

Код
Выбрать все
СообщитьвФайл(миля("Файл ")+ФайлВладелец+Я(" залочен (")+Лок+")","ВставкаЛистаExcel"); 



  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #13 - 14. Июня 2012 :: 13:07
Печать  
alyuev писал(а) 14. Июня 2012 :: 12:44:
Как пример (в качестве зарядки для ума Улыбка ), попробуйте вычленить выделенное в строке:

Занефиг: Я\("([^"]|"".)*"\)
Только чем это поможет? Регулярные выражения не очень хорошо подходят для разбора синтаксиса.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
alyuev
God Member
*****
Отсутствует


Гражданин Вселенной

Сообщений: 855
Местоположение: Одесса
Зарегистрирован: 07. Декабря 2007
Пол: Мужской
Re: regexp, ПолучитьТекстМодуля и пр.
Ответ #14 - 14. Июня 2012 :: 13:12
Печать  
А здесь?

Код
Выбрать все
Сообщить(Я("Валюта платежа и "+?(ДатаК<ДатаНовогоВиденияКурса,"основная валюта","валюта клиента")+" совпадают, устанавливать курс не имеет смысла."),"!"); 

  

1C 7.7.025; 1C++ 3.2.4.3; Formex 2.0.5.94; 1sqlite
Наверх
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать