#python #regex
#python #регулярное выражение
Вопрос:
В моем коде у меня есть представления, определенные, как показано ниже.
VIEW Company_Person_Sd IS
Prompt = 'Company'
Company.Prompt = 'Company ID'
SELECT company_id company_id,
emp_no emp_no,
Get_Person(company_id, emp_no) person_id,
cp.rowid objid,
to_char(cp.rowversion) objversion,
rowkey objkey
FROM companies cp;
В одном файле может быть определено более одного представления (обычно их 20 или более).
Я хочу получить полное представление, используя регулярное выражение в python.
Я сделал то же самое с методом, как показано ниже, используя следующее регулярное выражение. (и это сработало нормально)
methodRegex = r"^s*((FUNCTION|PROCEDURE)s (w ))(.*?)BEGIN(.*?)^ENDs*(w );"
methodMatches = re.finditer(methodRegex, fContent, re.DOTALL | re.MULTILINE | re.IGNORECASE | re.VERBOSE)
for methodMatchNum, methodMatch in enumerate(methodMatches, start=1):
methodContent=methodMatch.group()
methodNameFull=methodMatch.group(1)
methodType=methodMatch.group(2)
methodName=methodMatch.group(3)
пример метода
PROCEDURE Prepare___ (
attr_ IN OUT VARCHAR2 )
IS
----
BEGIN
--
END Prepare___;
PROCEDURE Insert___ (
attr_ IN OUT VARCHAR2 )
IS
----
BEGIN
--
END Insert___;
Когда я пытаюсь сделать то же самое для представлений, он выдает неверный вывод.
На самом деле я не мог найти, как поймать конец представления. Я также пробовал использовать точку с запятой, что дало неверный вывод.
Мое регулярное выражение для представлений
viewRegex = r"^s*(VIEWs (w ))(.*?)SELECT(.*?)^FROMs*(w );"
Пожалуйста, помогите мне выяснить, где я делаю это неправильно. Заранее спасибо.
Ответ №1:
Если у вас много представлений в одном файле, другим вариантом является предотвращение использования .*?
with re.DOTALL
для предотвращения ненужного возврата.
Вместо этого вы можете сопоставить части от VIEW
SELECT
до FROM
, проверяя, что то, что находится между ними, не является другим одним из ключевых слов, чтобы предотвратить слишком сильное сопоставление с использованием отрицательного прогноза (при условии, что они не могут встречаться между ними)
Для последней части после FROM вы можете сопоставить символы word, необязательно повторяющиеся символами пробела и снова символами word.
^(VIEWs (w ))(.*(?:n(?!SELECT|VIEW|FROM).*)*)nSELECTs (.*(?:n(?!SELECT|VIEW|FROM).*)*)nFROMs (w (?:s w ));
Шаблон соответствует:
^
Начало строки(VIEWs (w ))
Группа захвата для ПРЕДСТАВЛЕНИЯ, за которой следует группа для символов слова(.*(?:n(?!SELECT|VIEW|FROM).*)*)
Группа захвата, соответствующая остальным строкам, и все строки, которые не начинаются с ключевого словаnSELECTs
Сопоставьте новую строку, ВЫБЕРИТЕ и 1 пробел cahr(.*(?:n(?!SELECT|VIEW|FROM).*)*)
Группа захвата, соответствующая остальным строкам, и все строки, которые не начинаются с ключевого словаnFROMs
Сопоставьте символы новой строки, FROM и 1 пробел(w (?:s w ))
; Группа захвата для значения FROM, совпадающего с 1 символами word и, при необходимости, повторяющегося с помощью пробельных символов и символов word
Демонстрация регулярных выражений
Например (вы можете опустить re.VERBOSE
и re.DOTALL
)
import re
methodRegex = r"^^(VIEWs (w ))(.*(?:n(?!SELECT|VIEW|FROM).*)*)nSELECTs (.*(?:n(?!SELECT|VIEW|FROM).*)*)nFROMs (w (?:s w ));"
fContent = ("VIEW Company_Person_Sd ISn"
" Prompt = 'Company'n"
" Company.Prompt = 'Company ID'n"
"SELECT company_id company_id,n"
" emp_no emp_no,n"
" Get_Person(company_id, emp_no) person_id,n"
" cp.rowid objid,n"
" to_char(cp.rowversion) objversion,n"
" rowkey objkeyn"
"FROM companies cp;")
methodMatches = re.finditer(methodRegex, fContent, re.MULTILINE | re.IGNORECASE)
for methodMatchNum, methodMatch in enumerate(methodMatches, start=1):
methodContent = methodMatch.group()
methodNameFull = methodMatch.group(1)
methodType = methodMatch.group(2)
methodName = methodMatch.group(3)
Комментарии:
1. Хорошее объяснение. Спасибо
Ответ №2:
Вы не получите никакого совпадения с viewRegex
, потому что оно совпадает только тогда, когда между и есть только символы word ( [a-zA-Z0-9_]
) FROM
;
. В то время как ваш пример также включает пробел. Поэтому также учитывайте пробелы:
viewRegex = r"^s*(VIEWs (w ))(.*?)SELECT(.*?)^FROMs*([ws] );"
Комментарии:
1. Спасибо, и все сработало нормально.