expressão regular para corresponder apenas o primeiro arquivo em um conjunto de arquivos RAR
Pergunta
Para ver o arquivo para chamar o comando unrar on, é preciso determinar qual arquivo é o primeiro no conjunto de arquivos.
Aqui estão alguns nomes de arquivo de amostra, dos quais - naturalmente - apenas o primeiro grupo deve ser acompanhado:
yes.rar
yes.part1.rar
yes.part01.rar
yes.part001.rar
no.part2.rar
no.part02.rar
no.part002.rar
no.part011.rar
Uma maneira (limitado) para fazê-lo com expressões regulares compatíveis PCRE é esta:
.*(?:(?<!part\d\d\d|part\d\d|\d)\.rar|\.part0*1\.rar)
Isto não funcionou em Ruby quando eu testei em Rejax no entanto.
Como você escrever um rubi expressão regular compatível para corresponder apenas o primeiro arquivo em um conjunto de arquivos RAR?
Solução
A resposta curta é que não é possível construir um único regex para satisfazer o seu problema. O Ruby 1.8 não tem afirmações LookAround (o (?
1) Use mais de um regex para fazê-lo.
def is_first_rar(filename)
if ((filename =~ /part(\d+)\.rar$/) == nil)
return (filename =~ /\.rar$/) != nil
else
return $1.to_i == 1
end
end
2) Use o mecanismo de regex para Ruby 1.9, Oniguruma . Ele suporta afirmações LookAround, e você pode instalá-lo como uma jóia para Ruby 1.8 . Depois disso, você pode fazer algo como isto:
def is_first_rar(filename)
reg = Oniguruma::ORegexp.new('.*(?:(?<!part\d\d\d|part\d\d|\d)\.rar|\.part0*1\.rar)')
match = reg.match(filename)
return match != nil
end
Outras dicas
Não confie nos nomes dos arquivos para determinar qual é o primeiro. Você vai acabar encontrando um caso extremo onde você obter o arquivo errado.
do RAR cabeçalhos irá dizer-lhe qual arquivo é o primeiro em no volume, assumindo que eles foram criados em uma versão um pouco-recente da RAR.
HEAD_FLAGS sinalizadores de bit:
2 bytes0x0100 - Em primeiro lugar o volume (definido apenas por RAR 3,0 e mais tarde)
Então abra cada arquivo e examinar os cabeçalhos RAR, olhando especificamente para a bandeira que indica qual arquivo é o primeiro volume. Isso nunca irá falhar, desde que o arquivo não está corrompido. Eu fiz meus próprios testes com abrangendo arquivos RAR e seus cabeçalhos estão corretas de acordo com o link acima.
Esta é uma maneira muito, muito mais seguro para determinar qual arquivo é o primeiro em uma série como esta.
Pessoalmente, eu não usaria (extended) expressões regulares neste caso (ou pelo menos não apenas um para fazer tudo). O que há de errado com codificação isso em, por exemplo, algumas if
s?
Não sou especialista regex mas aqui é a minha tentativa
^(yes|no)\.(rar|part0*1\.rar)$
Substitua "sim | não" com o nome do arquivo real. I combinando contra seus exemplos para ver se ele só iria coincidir com o primeiro conjunto, portanto, o "sim | não". Na regex
UPDATE: fixo de acordo com o comentário. Não sei por que o usuário não saberia o nome do arquivo para que eu não corrigir essa parte ...