Найти и подсчитать экземпляр подстроки в нескольких строках с помощью python

#python #regex #string #substring

#python #регулярное выражение #строка #подстрока

Вопрос:

У меня есть sql-запрос в python с несколькими вложенными запросами. Таким образом, настройка представляет собой несколько подстрок в более крупной строке. Я хотел бы проверить количество экземпляров строки в подстроках. Немного сложнее, чем то, что я видел, и ценю помощь.

Настройте так —

 qry = ''' 
with 
qry_1 as ( 
   SELECT ID, 
          NAME
   FROM   ( ... other code...
),
qry_2 as ( 
    SELECT coalesce (table1.ID, table2.ID) as ID,
           NAME
   FROM (...other code...
),
qry_3 as (
     SELECT id.WEATHER AS WEATHER_MORN,
            ROW_NUMBER() OVER(PARTITION BY id.SUN
                ORDER BY id.TIME) AS SUN_TIME,
            id.RAIN,
            id.MIST
   FROM (...other code..
)
'''
 

И я хотел бы подсчитать экземпляры ID for внутри qry_1, qry_2, qry_3 .

Что-то, что я думаю, будет использовать re.findall , а затем поиск по подстроке?

 re.findall(r'as ( select (. ?) from (',qry)
 

А затем найти и подсчитать экземпляры ID внутри этого? Где результат равен 2. Но я не уверен, как это сделать…

Ответ №1:

Вы можете разделить запросы CTE, а затем использовать re.findall для усеченной версии подзапроса:

 qry = ''' 
with 
qry_1 as ( 
  SELECT ID, 
      NAME
  FROM   ( ... other code...
),
qry_2 as ( 
  SELECT coalesce (table1.ID, table2.ID) as ID,
       NAME
FROM (...other code...
),
qry_3 as (
  SELECT WEATHER
FROM (...other code..
)
'''

def get_cols(s):
   [cte_name] = re.findall('^w (?=sas)|(?<=withs)w (?=sas)', s)
   cols = re.findall('(?<=ass)[w.] |(?<=SELECTs)[w.] |(?<=,s)[w.] ', s)
   return [cte_name, cols]

#dictionary with the cte name as the key, and the columns as the values
v = dict(get_cols(re.sub('coalesces(. )|[sn] ', ' ', i)) for i in re.split('(?<=)),(?:s )*n', qry))
#filter the dictionary above to only include desired column names
r = {a:k if (k:=[i for i in b if i in {'NAME', 'ID'}]) else None for a, b in v.items()}
 

Вывод:

 {'qry_1': ['ID', 'NAME'], 'qry_2': ['ID', 'NAME'], 'qry_3': None}
 

Комментарии:

1. отлично, это действительно полезно! если бы я хотел включить в счетчик, содержит ли строка ID также, например, экземпляр table.ID , могу ли я это сделать?

2. @paranormaldist пожалуйста, посмотрите мое недавнее редактирование

3. это здорово! и один дополнительный вопрос, если возможно, включить ID или NAME в вывод. {'qry_1': 'ID', 'NAME', 'qry_2': 'ID','NAME', 'qry_3': None}

4. @paranormaldist пожалуйста, посмотрите мой недавний

5. @paranormaldist Спасибо за обновление с новой qry строкой, пожалуйста, посмотрите мою недавнюю правку.