Renomear em lote filmes usando o Regex

1

Eu tenho tentado renomear alguns arquivos de filme usando expressões regulares, mas até agora eu fui apenas um pouco bem-sucedido. O objetivo é analisar arquivos como este:

2001.A.Space.Odyssey.1968.720p.BluRay.DD5.1.x264-LiNG.mkv

E renomeie-os assim:

2001 A Space Odyssey (1968).mkv

Eu criei o padrão: ^(.+)\.(\d{4}).+\.(mp4|avi|mkv)$

Com a saída: ().

Agora, isso funciona perfeitamente quando tenho filmes com títulos de uma só palavra, mas quando há mais de uma palavra separada por um período, a regex não consegue pegar nada.

O que estou fazendo de errado aqui?

    
por Nate Mara 29.10.2013 / 04:30

2 respostas

3

Seu padrão parece funcionar bem para mim com esse nome de arquivo de exemplo e Perl como o mecanismo de regex:

$ echo '2001.A.Space.Odyssey.1968.720p.BluRay.DD5.1.x264-LiNG.mkv' | 
    perl -npe 's/^(.+).(\d{4}).+.(mp4|avi|mkv)$/ ()./'

2001.A.Space.Odyssey (1968).mkv

A única coisa que eu mudaria é escapar do . onde você realmente quer que eles se refiram a um ponto e não a um curinga. Em particular, provavelmente é seguro assumir o período final antes que a extensão do arquivo seja realmente um período - não tenho certeza sobre o período entre o título e o ano.

    
por 29.10.2013 / 05:28
0

Eu passei várias horas escrevendo e ajustando um script python para fazer exatamente isso. Uma das coisas que eu encontrei é que muitas vezes não é tão preto e branco como lidar com um único arquivo como este.

Nota: Isso é baseado em python, o que exigirá ajustes se você estiver trabalhando em outro idioma

Por que estou lhe dizendo isso:

  • Às vezes, o arquivo é mal nomeado, enquanto a pasta pai é nomeada como você indicou.
  • Às vezes, você recebe artigos ou numerais romanos no meio que devem / não devem ser maiúsculos
  • Você pode mover "O" até o final, como em ","
  • Às vezes, falta a data
  • Em seu exemplo específico, seu regex terá dificuldade em diferenciar entre 2001 e 1968.

No final, você pode descobrir que dividir sua função em vários blocos (ou usando correspondência) ajudará você a desmembrá-la.

Aqui está um resumo básico do que acabei usando:

1: defina algumas variáveis globais para permitir flexibilidade:

renamePattern = "%titlethe% %quality% (%year%).%ext%" 
articles = ['a', 'an', 'of', 'the', 'is', 'on', 'at', 'in', 'and']
roman = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII']

2: Verifique se o arquivo tem um nome válido, caso contrário, suba e verifique a pasta:

if (re.search(".+(108|72)0p?.+", folder) and re.search(".+(\s|\.)(19|20)[0-9][0-9](.*|(?!p))", folder)):
#appears to have a valid quality and date, return folder

elif (re.search(".+(108|72)0p?.+", file) and re.search(".+(\s|\.)(19|20)[0-9][0-9](.*|(?!p))", file)):
#appears to have a valid date and quality, return file

else:
#return None, which will fail the script

3: Faça alguma mágica

f = re.sub("\.", " ", file_string)
s = re.sub("\.", "", s)

if re.search("\%\w+\%", s):
    if re.search("titlethe", s):
        s = titleCase(f, articles)
        s = re.sub("\s(19|20)[0-9][0-9](.*|(?!p))$", "", s)
        s = re.sub("\s?(108|72)0p\s?", "", s, re.I)
        if re.search("^The\s", s):
            s = re.sub("^The\s", "", s) + ", The"
    elif re.search("thetitle", s):
        #do thetitle stuff
        s = titleCase(f, articles)
        s = re.sub("\s(19|20)[0-9][0-9](.*|(?!p))$", "", s)
        s = re.sub("\s?(108|720)p\s?", " ", s, re.I)
    elif re.search("quality", s):
        if re.search(".*1080p?.*", f, re.I):
            s = "1080p"
        elif re.search(".*720p?.*", f, re.I):
            s = "720p"
    elif re.search("year", s):
        p = re.compile(".+\s(?P<year>(19|20)[0-9][0-9])(.*|(?!p))")
        if p is not None:
            m = p.match(f)
            s = m.group('year')
    elif re.search("ext", s):
        s = getExt(file_name)
return re.sub("[ ]{2,}", " ", s)

Edit: No final, se você realmente quer apenas o script python que eu escrevi, me avise e postarei no sourceforge ou git.

    
por 29.10.2013 / 07:32