2016-08-11 2 views
1

У меня есть 2 файла, и я хочу получить все строки из файла2 (fsearch), которые содержат любую строку из файла1 (forig)
Я написал простой скрипт python, который выглядит так:Python cross-file search with regexp

def search_string(w, file): 
     global matches 
     reg = re.compile((r'(^|^.*\|)' + w.strip("\r\n") + r'(\t|\|).*$'), re.M) 
     match = reg.findall(file) 
     matches.extend(match) 

fsearch_text = fsearch.read() 
for fword in forig: 
     search_string(fword, fsearch_text) 

Есть около 100 000 строк в file1 и около 200 000 строк в file2, так что мой сценарий занимает около 6 часов.
Есть ли лучший алгоритм для достижения той же цели за меньшее время?

Edit: я должен был обеспечить пример, почему мне нужно регулярное выражение:
Я ищу список слов в file1 и пытается сопоставить их с переводами из file2. Если я не использую regexp для ограничения возможных совпадений, я также сопоставляю переводы для слов, которые содержат только слово I, как часть себя, например:
Word I search: 浸 し
Согласованное слово: お 浸 し | 御 浸 し | 御し た し & n отварная зелень в соевом соусе с бонитовым соусом (овощная боковая тарелка)
Итак, мне нужно ограничить начало матча либо^или |, либо конец матча \ t или |, но зафиксировать всю строку

+0

использование регулярного выражения и «сравнить каждую строку с каждой строкой» делает его настолько медленным ... 100000 * 200000 = 2e10 сравнения с регулярным выражением – m13r

+0

после вашего редактирования, возможно ли индексировать каждое слово? – lemon

ответ

0

Предполагая, что вы можете иметь оба файла в памяти. Вы можете прочитать их и отсортировать.

После этого вы можете линейно сравнить линии.

f1 = open('e:\\temp\\file1.txt') 

lines1 = sorted([line for line in f1]) 

f2 = open('e:\\temp\\file2.txt') 

lines2 = sorted([line for line in f2]) 

i1 = 0 
i2 = 0 
matchCount = 0 
while (i1 < len(lines1) and i2 < len(lines2)): 
    line1 = lines1[i1] 
    line2 = lines2[i2] 
    if line1 < line2:  
     i1 += 1 
    elif line1 > line2: 
     i2 += 1 
    else: 
     matchCount += 1 
     i2 += 1 

print('matchCount')  
print(matchCount) 
+1

должно быть наоборот: подсчитайте все строки из файла2, которые находятся в файле1 ... – m13r

+1

@ m13r, да, вы правы. Я редактирую его. Спасибо – lemon

+0

Спасибо, но сортировка не очень поможет, так как начало матча может быть не в начале строки. Я должен был опубликовать примеры изначально, но я добавил их сейчас –

0

Если это возможно для вас использовать UNIX/GNU/Linux команды, которые вы можете сделать это:

# fill example files 
for i in {1..100000}; do echo $RANDOM; done > file1.txt 
for i in {1..200000}; do echo $RANDOM; done > file2.txt 

# get every line of file2.txt which is also in file1.txt 
# for static string matching: 
grep -F -x -f file1.txt file2.txt 

# for regex matching use (regular expressions in file1.txt): 
grep -f file1.txt file2.txt 

grep оптимизирован для таких операций, поэтому вышеуказанный вызов занимает меньше второго (у посмотрите на this).

+0

Это работает чудеса для поиска без регулярного выражения. Я пытался писать регулярные выражения в файле и grep их из файла2, но, по-видимому, 4gb оперативной памяти не хватает, поскольку я получаю: grep.exe: память исчерпана –

+0

Я обновил свой вопрос, чтобы иметь регулярное выражение в file1. Насколько велики файлы, которые вы используете? И сколько строк в файлах? – m13r