Подсчет совпадений из словарного файла в окне, окружающем ключевое слово

Для своего исследования я пытаюсь подсчитать из корпуса, сколько раз (в одном случае) ряд составных терминов (например, Угроза безопасности), хранящихся в файле, по 1 строке на фразу, появляется в окне из 16 слов целевое ключевое слово (например, объект). Я не программист, пытаюсь разбить его на 2 элемента: сначала извлеките файл из корпуса, где у меня есть совпадение по целевому ключевому слову, с 8 словами до и после. Затем попробуйте сопоставить мой "словарный файл" с этим фрагментом. Я нахожусь на части 1, попробовал это, но я просто получаю сообщение <_sre.SRE_Match at 0x028FFE78> и пытаюсь использовать repr: Любые предложения оценены или другие способы сделать это. В конечном итоге мне нужен файл экспорта, в котором слова из моего словаря имеют счетчик после них, указывающий, как часто они были найдены в этом окне с моим целевым словом. Использование логики re.search основано на том, что я нашел на этой доске объявлений, поэтому я попробовал это:

input=open("Corpus.txt", "r")
matches=[]
lines=input.readlines()
for line in lines:
  m=re.search(r'(\S+\s+){0,8}facility(\s+\S+){0,8}',line)
  if m:
    matches.append(m)
    for m in matches:
      output.write(str(m))
      output.close()

Любая помощь приветствуется, Пол

1 ответ

Решение

Ваш корпус уже токенизирован? Вы должны действительно убедиться, что это так.

Во всяком случае, я думаю, что вы заинтересованы в группах объекта сопоставления:

output.write(''.join(m.groups()) + '\n')

Затем вы обнаружите, что ваши группы будут захватывать только последнее слово каждого окна. Вам нужно поставить лишнюю пару скобок:

m = re.search(r'((?:\S+\s+){0,8})facility((?:\s+\S+){0,8})', line)

(?:...) является не захватывающей группой: она определяет область действия {0,8}, но это не дает вам дополнительную группу в результате.

Загляните в официальный Python RegEx Howto или поищите в Интернете учебник по RegEx. И в любом случае, может быть, вам стоит искать готовый инструмент, а не заново изобретать колесо.

РЕДАКТИРОВАТЬ:
Чтобы сопоставить несколько вхождений ключевого слова в одной строке, используйте re.findall() (возвращает список) или re.finditer() (возвращает итератор):

context = re.findall(r'((?:\S+\s+){0,8})facility((?:\s+\S+){0,8})', line)

context будет список пар, т.е. левое и правое окно для каждого вхождения ключевого слова. Обратите внимание, однако, что он все равно не будет работать, если два вхождения одного и того же ключевого слова содержат менее 8 слов, например.

бар foo bar bla foo bar баз центр foo bar

сгенерирует только одно совпадение для первого вхождения "средства", имея второе в правом окне. Второе "средство" не будет генерировать собственное совпадение, так как re.findall() не выполняет перекрывающихся совпадений, что означает, что он будет искать другое "средство" только после окончания правильного контекста. Это также означает, что, если между ними находится от 9 до 15 слов, левое окно второго "объекта" будет меньше, чем первое, которое уже было использовано.

Другие вопросы по тегам