поиск строки с возвращением совпавшей строки в python - PullRequest
3 голосов
/ 20 июля 2011

Я новичок в python. Я хочу сопоставить строку в некоторых строках файла. Допустим, у меня есть строка:

british    7
German     8
France     90

И у меня есть несколько строк в файле, например:

<s id="69-7">...Meanwhile is the studio 7 album by British pop band 10cc.</s>
<s id="15-8">...And Then There Were Three... is the ninth studio album by the german band Genesis 8 and was released in 1978.</s>
<s id="1990-2">Magnum Nitro Express is a France centerfire fire rifle cartridge 90.</s>

Я хочу получить вывод как:

<s id="69-7">...Meanwhile is the studio <w2>7</w2> album by <w1>British</w1> pop band 10cc.</s>
<s id="15-8">...And Then There Were Three... is the ninth studio album by the <w1>german</w1> band Genesis <w2>8</w2> and was released in 1978.</s>
<s id="1990-2">Magnum Nitro Express is a <w1>France</w1> centerfire fire rifle cartridge <w2>90</w2>.</s>

Я попытался с помощью следующего кода:

for i in file:      
    if left in i and right in i:
        line = i.replace(left, '<w1>' + left + '</w1>')
        lineR = line.replace(right, '<w2>' + right + '</w2>')
        text = text + lineR + "\n"
        continue
     return text

Но это также соответствует строке из id.например.

<s id="69-<w2>7</w2>">...Meanwhile is the studio <w2>7</w2> album by <w1>British</w1> pop band 10cc.</s>

Итак, есть ли способ найти строку как слова, а не как символ, чтобы я мог убежать <s id="69-<w2>7</w2>">?

Заранее благодарен за любую помощь.

Ответы [ 3 ]

4 голосов
/ 20 июля 2011

У меня есть кое-что довольно сложное, но я написал это в спешке, и на данный момент он делает свою работу.

Обратите внимание, что:

  • Я добавил 'во Франции'after Между тем, это студийный альбом 7 британской поп-группы 10cc
    , который изменен только British

  • ' 1978 'в немецкой группой Genesis 8, выпущенной в 1978 году. не изменяется, тогда как '8' изменяется.

Вот почему это сложно.

Но я боюсь, что, несмотря на это осложнение, оно не будет точным для всех возможных предложений.

Необходимо усовершенствовать, чтобы idi всегда было правильным названием музыкальной группы, а не всегда первым, как это в настоящем решении.Но это тяжелая работа, не зная, что именно вы хотите

ss ='''british    7
German     8
France     90'''


text = '''<s id="69-7">...Meanwhile is the studio 7 album by British pop band 10cc in France.</s>
<s id="15-8">...And Then There Were Three... is the ninth studio album by the german band Genesis 8 and was released in 1978.</s>
<s id="1990-2">Magnum Nitro Express is a France centerfire fire rifle cartridge 90.</s>
'''




import re
regx = re.compile('^(.+?)[ \t]+(\d+)',re.MULTILINE)




dico = dict((a.lower(),b) for (a,b) in regx.findall(ss))
print 'dico==',dico
print '\n\n'



rogx = re.compile('(<s id="[\d-]+">|</s>\r?\n)')
splitted = rogx.split(text)
print 'splitted==\n',splitted

print '=================\n'

def repl(mat):
    idi = (b for (a,b) in the if b).next().lower()
    x,y = mat.groups()
    if x:
        if dico[idi.lower()]==x:
            return '<w2>%s</w2>' % x
        else:
            return x
    if y :
        if y.lower()==idi:
            return '<w1>%s</w1>' % y
        else:
            return y

rigx = re.compile('(\d+)|(' + '|'.join(dico.keys()) + ')',re.IGNORECASE)

for i,el in enumerate(splitted[0::2]):
    if el:
        print '-----------------------------'
        print '* index in splitted==',2*i
        print '\n* el==\n',repr(el)
        print '\n* rigx.findall(el)==\n',rigx.findall(el)
        the = rigx.findall(el)
        print '\n* modified el:\n',rigx.sub(repl,el)
        splitted[2*i] = rigx.sub(repl,el)


print '\n\n##################################\n\n'

print 'modified splitted==\n',splitted
print
print ''.join(splitted)

результат

dico== {'german': '8', 'british': '7', 'france': '90'}



splitted==
['', '<s id="69-7">', '...Meanwhile is the studio 7 album by British pop band 10cc in France.', '</s>\n', '', '<s id="15-8">', '...And Then There Were Three... is the ninth studio album by the german band Genesis 8 and was released in 1978.', '</s>\n', '', '<s id="1990-2">', 'Magnum Nitro Express is a France centerfire fire rifle cartridge 90.', '</s>\n', '']
=================

-----------------------------
* index in splitted== 2

* el==
'...Meanwhile is the studio 7 album by British pop band 10cc in France.'

* rigx.findall(el)==
[('7', ''), ('', 'British'), ('10', ''), ('', 'France')]

* modified el:
...Meanwhile is the studio <w2>7</w2> album by <w1>British</w1> pop band 10cc in France.
-----------------------------
* index in splitted== 6

* el==
'...And Then There Were Three... is the ninth studio album by the german band Genesis 8 and was released in 1978.'

* rigx.findall(el)==
[('', 'german'), ('8', ''), ('1978', '')]

* modified el:
...And Then There Were Three... is the ninth studio album by the <w1>german</w1> band Genesis <w2>8</w2> and was released in 1978.
-----------------------------
* index in splitted== 10

* el==
'Magnum Nitro Express is a France centerfire fire rifle cartridge 90.'

* rigx.findall(el)==
[('', 'France'), ('90', '')]

* modified el:
Magnum Nitro Express is a <w1>France</w1> centerfire fire rifle cartridge <w2>90</w2>.


##################################


modified splitted==
['', '<s id="69-7">', '...Meanwhile is the studio <w2>7</w2> album by <w1>British</w1> pop band 10cc in France.', '</s>\n', '', '<s id="15-8">', '...And Then There Were Three... is the ninth studio album by the <w1>german</w1> band Genesis <w2>8</w2> and was released in 1978.', '</s>\n', '', '<s id="1990-2">', 'Magnum Nitro Express is a <w1>France</w1> centerfire fire rifle cartridge <w2>90</w2>.', '</s>\n', '']

<s id="69-7">...Meanwhile is the studio <w2>7</w2> album by <w1>British</w1> pop band 10cc in France.</s>
<s id="15-8">...And Then There Were Three... is the ninth studio album by the <w1>german</w1> band Genesis <w2>8</w2> and was released in 1978.</s>
<s id="1990-2">Magnum Nitro Express is a <w1>France</w1> centerfire fire rifle cartridge <w2>90</w2>.</s>

РЕДАКТИРОВАНИЕ 1

Я исключил replmodel ()

repl() принимает значение rigx.findall (el)
Я добавил строку the = rigx.findall (el) для этого

3 голосов
/ 20 июля 2011

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

Что-то вроде

import re
left='british'
right='7'
i1 = re.sub('(?i)(\s+)(%s)(\s+)'%left, '\\1<w1>\\2</w1>\\3', i)
i2 = re.sub('(?i)(\s+)(%s)(\s+)'%right, '\\1<w2>\\2</w2>\\3', i1)
print(i2)

, что дает нам '<s id="69-7">...Meanwhile is the studio <w2>7</w2> album by <w1>British</w1> pop band 10cc.</s>'

И еслитакой подход приводит к ошибкам, вы можете попробовать более тонкий код, например

import re

def do(left, right, line):
    parts = [x for x in re.split('(<[^>]+>)', line) if x]
    for idx, l in enumerate(parts):
        lu = l.upper()
        if (not ('<s' in l or 's>' in l) and
            (left.upper() in lu and right.upper() in lu)):
            l = re.sub('(?i)(\s+)(%s)(\s+)'%left, '\\1<w1>\\2</w1>\\3', l)
            l = re.sub('(?i)(\s+)(%s)(\s+)'%right, '\\1<w2>\\2</w2>\\3', l)
            parts[idx] = l

    return ''.join(parts)


line = '<s id="69-7">...Meanwhile is the studio 7 album by British pop band 10cc.</s>'
print(do('british', '7', line))
print(do('british', '-7', line))
1 голос
/ 20 июля 2011

Лучший способ - использовать регулярные выражения.Но в случае, если у 'left' и 'right' всегда будет хотя бы один пробел в конце и в начале, вы можете использовать простой трюк (просто добавьте пробел и пробел в ваш паттерн):

line = file.replace(' ' + left + ' ', ' <w1>' + left + '</w1> ')
lineR = line.replace(' ' + right + ' ', ' <w2>' + right + '</w2> ')        
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...