почему ГРУППА РЕГУЛЯРНЫХ ВЫРАЖЕНИЙ иногда рассматривает список строк как строку, а иногда как список?

#python #regex #regex-group

Вопрос:

Я анализирую PDF-файлы и извлекаю текст с помощью регулярных выражений.

Вот пример text_pos

 text_pos = [['5. qwe', 'LLL LLL  23', 'zzz qqq ewq (qwe ewq)', 'ewq nqwe', 'eee  wwww', 'qwewww'],
            ['LLL LLL  54', 'ttt qqq (eee www)', 'eeeeneee', 'aaaaa nwww'],
            ['K K K K K K   K K K K K K K   7 /', '111', 'zzz qqq qwe (ewq Lee)', 'qweeneen', 'eewwww']]
 

Вот фрагмент моего кода

     text_pos = []
    .
    .
    .

    # REGEX
    aaa = re.compile(r'(Ks Ks Ks Ks Ks Ks Ks Ks Ks Ks Ks Ks Ks d.*)(zzz|ttt)', flags = re.DOTALL | re.MULTILINE)
    bbb = re.compile(r'(LLLs LLL)(.*)(zzz|ttt)', flags = re.DOTALL | re.MULTILINE)
    ccc = re.compile(r'(zzz|ttts qqq)s (.*))', flags = re.DOTALL | re.MULTILINE)
    number = aaa.search(str(text_pos))
    number1 = bbb.search(str(text_pos))
    asker = ccc.search(str(text_pos))
    try:
        if number:
            number.group(0)
    except:
        pass
    try:
        if number1:
            number = number1.group(2)
    except:
        pass
    try:
        if asker:
            asker.group(1)
    except:
        pass
    
    data.append([number, asker])

df1 = pd.DataFrame(data, columns =['text', 'number']) 
 

регулярное выражение как-то работает, но иногда кажется, что оно рассматривается text_pos как строка, а иногда нет (возвращается только re.Match object вместо реальных символов).

Желаемый результат:

 for v in df1['number']:
    print(v)

23
54
7 /111
 

 for v in df1['asker']:
    print(v)

qqq ewq (qwe ewq)
qqq (eee www)
qqq qwe (ewq Lee)
 

Фактический объем производства:

 for v in df1['number']:
    print(v)

23', 'zzz qqq ewq (qwe ewq)', 'ewq nqwe', 'eee  wwww', 'qwewww'
54', 'ttt qqq (eee www)', 'eeeeneee', 'aaaaa nwww
<re.Match object; span=(2, 3470), match="K K K K K K   K K K K K K K   7 /', '111', 'zzz >
 

 for v in df1['asker']:
    print(v)

<re.Match object; span=(0, 59), match="['5. qwe', 'LLL LLL  23', 'zzz qqq>
<re.Match object; span=(24, 2203), match='ttt qqq (eee www)', 'qwe>
<re.Match object; span=(47, 3015), match="zzz qqq qwe (ewq Lee)', 'q>
 

ОТРЕДАКТИРУЙТЕ следующее предложение викторов: попробуйте выполнить регулярное выражение для каждой строки в каждом списке

 for i in text_pos:
    for j in i:
        m = re.search(aaa, j)
        if m:
            number = m.group(0)
 

ВОЗВРАТ

 for v in df1['number']:
    print(v)

<re.Match object; span=(2, 3470), match="K K K K K K   K K K K K K K   7 /', '111', 'zzz >
<re.Match object; span=(2, 3470), match="K K K K K K   K K K K K K K   7 /', '111', 'zzz >
<re.Match object; span=(2, 3470), match="K K K K K K   K K K K K K K   7 /', '111', 'zzz >
 

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

1. Регулярное выражение работает только со строками, но никогда с объектами.

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

3. text_pos это список списков. Когда вы приводите его к строке, он становится «неуклюжей» строкой, похожей на список. Это не то, как вы запускаете регулярные выражения в строковых списках. Вам нужно запустить регулярное выражение для каждой строки в каждом списке.

4. Извините, я решил присмотреться повнимательнее и не понял, где df1['number'] заявлено ваше. Кроме того, в чем сейчас проблема? Просто получаешь текст совпадения? Возвращение m.group() и не только m (результат re.search ).

5. Посмотрите: number = aaa.search(str(text_pos)) и asker = ccc.search(str(text_pos)) , а затем data.append([number, asker]) и df1 = pd.DataFrame(data, columns =['text', 'number']) приведите к отображению объекта данных соответствия, а не целых значений соответствия.

Ответ №1:

Я не могу объяснить, почему следующее работает, но это так

     text_list = ' '.join(map(str, text_pos))
  
    aaa = re.compile(r'(Ks Ks Ks Ks Ks Ks Ks Ks Ks Ks Ks Ks K)(([^zzz|ttt]*).*)', flags = re.DOTALL | re.MULTILINE)
    ccc = re.compile(r'(LLLs LLL)(([^zzz|ttt]*).*)', flags = re.DOTALL | re.MULTILINE)
    
    number = aaa.search(text_list)
    number1 = ccc.search(text_list)
    
    if number:
        number = number.group(3)
    else:
        number = number1.group(3)

data.append([text_list, number])
fake_file_handle.close()

df1 = pd.DataFrame(data, columns =['text_list', 'WP / number'])


for v in df1['number']:
    print(v)

23
54
7 / 1864 
 

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

1. Вы получаете доступ к значению группы здесь, number.group(3) . При добавлении в data.append([text_list, number]) вы number уже являетесь строкой , а не объектом.