Jump to content

Dúvida em Regular Expression


Recommended Posts

Tenho este texto:

1: Int J Cancer. 2008 May 19; [Epub ahead of print]

Statin use and the risk of prostate cancer: A metaanalysis of 6 randomized

clinical trials and 13 observational studies.

Bonovas S, Filioussi K, Sitaras NM.

Department of Pharmacology, School of Medicine, University of Athens, Athens,

Greece.

Statins have been suggested to prevent prostate cancer. Our aim was to examine

statin use in relation to both total prostate cancer and the more clinically

important advanced prostate cancer, through a detailed metaanalysis of the

epidemiologic studies published on the subject in peer-reviewed literature. A

comprehensive search for articles published up to November 2007 was performed,

reviews of each study were conducted and data were abstracted. Prior to

metaanalysis, the studies were evaluated for publication bias and heterogeneity.

Pooled relative risk (RR) estimates and 95% confidence intervals (CIs) were

calculated using the random-effects model. Subgroup and sensitivity analyses

were also performed. Nineteen studies [6 randomized clinical trials (RCTs), 6

cohort and 7 case-control studies] contributed to the analysis. There was no

evidence of an association between statin use and total prostate cancer among

either RCTs (RR = 1.06, 95% CI: 0.93-1.20) or the observational studies (RR =

0.89, 95% CI: 0.65-1.24). However, high heterogeneity was detected among the

observational studies. Moreover, long-term statin use did not significantly

affect the risk of total prostate cancer (RR = 0.93, 95% CI: 0.77-1.13). In

contrast, synthesis of the available reports that had specifically examined

statin use in relation to advanced prostate cancer indicated a protective

association (RR = 0.77, 95% CI: 0.64-0.93). Our results do not support the

hypothesis that statins reduce the risk of total prostate cancer. However,

further research is required to investigate whether the particular association

of statin use with lower risk of advanced prostate cancer is indeed causal. ©

2008 Wiley-Liss, Inc.

PMID: 18491405 [PubMed - as supplied by publisher]

Quero separar parágrafo a parágrafo e, tendo em conta que isto se repete várias vezes (são vários artigos), subdividir também por artigo. Ou seja, quero ter algo tipo:

( ('1:', 'Int J Cancer. 2008 May 19; [Epub ahead of print]', 'Statin use and the risk of prostate cancer: A metaanalysis of 6 randomized clinical trials and 13 observational studies.', etc etc), ('2:', etc etc etc) )

O mais longe que consegui ir foi: '(\d+): ([^\n]+)\n+'

Encontra-me a primeira linha toda: '1:', 'Int J Cancer. 2008 May 19; [Epub ahead of print]'

Estou sem ideias...

Link to comment
Share on other sites

Bem, não foi com regular expressions que acabei por resolver isto. Mas ficou resolvido e deixo aqui a thread para alguma cabecinha das Regex me satisfazer a dúvida 😛

A minha solução foi:

    rawResults = urllib2.urlopen(url).read()
    
    regEx = re.compile(r'(\d+):')
    
    parsedResults = rawResults.split('\n\n')
    
    for i in parsedResults[1:-1]:
        if re.findall(regEx, i):
            print "\n"
            print "*"*50
            print "\n"
        print i.replace('\n', ' ')
Link to comment
Share on other sites

Guest id194

Esse teu código está em python (coisa que nunca usei), apesar do tópico não estar em nenhuma categoria especifica... Bem, eu diria que estas a complicar a querer usar regex (segundo o que percebi) para todo o texto. Ou seja, se fosse em PHP, recomenda o uso do explode('\n') depois era só fazeres um foreach ao array com uns ifs lá para dentro para ver se era inicio do artigo ou novo paragrafo.

Link to comment
Share on other sites

Pois, eu sei que está em Python porque foi a maneira como resolvi. Mas comecei a olhar para o problema com regex. Sempre me disseram que era mais eficiente e mais rápido, daí ter começado por aí. De qualquer maneira, o que eu queria era uma maneira de passar o meu raciocínio para regex: dividir o texto por '\n\n' (não por '\n') e dividir estes grupos de texto em vários artigos, quando se encontrasse algo tipo "X: " em que X é um inteiro.

Link to comment
Share on other sites

Guest id194

Continuo a achar a minha sugestão mais simples. Envolver regex pode criar problemas no futuro, basta não estar em pensado e ter um caractere a mais que lá se vai o esquema todo. Qual é o mal de separares para um array por \n e depois só tinhas de verificar (usando esse teu regex por exemplo) se a posição do array que estas a processar é ou não um novo paragrafo e trabalhar consoante a condição...

Acho que usar regex para TODO o texto é complicar e dá mais trabalho para ter a certeza que funcione a 100%. But that's just me...

Link to comment
Share on other sites

Guest id194

Esta última regez era só para verificar se a linha é um cabeçalho, a ideia é fazer como tu disseste, mas tem que se verificar quando se encontra um cabeçalho para poder saber por onde dividir.

Exacto, acho a forma mais simples. Em vez de processar todo o texto com regex.

Link to comment
Share on other sites

Já vos disse 👍 Acabei por resolver o meu problema com o script que ali está. Queria era uma maneira de fazer exactamente o mesmo, mas usando regex. Mas se é complicado e não compensa, também não vale a pena perder tempo nisso 🙂

De qualquer maneira, eu tinha que dividir de 2 maneiras o texto. A primeira, artigo a artigo, usando ou a regex que eu ali pus ou a que o pedrotuga pôs. Depois, usando outra que dividisse por '\n\n'. E queria juntar isto tudo numa só regex para ser tudo feito num passo. Mas ok, too complicated 😛

Link to comment
Share on other sites

Guest id194

Mas queres regex porquê? Para ser tudo num passo? Qual é o mal de mais um par de linhas de código? 🙂 Regex neste caso, não compensa e só complica. É o que eu acho...

Link to comment
Share on other sites

o facto de teres um número variável de parágrafos no artigo faz com que seja impossível passares isso para uma array apenas através de RegEx (tanto quanto sei).

Uma expressão deste tipo:

(\d+):\s*([^\n]+)\s*(?[^\n]+)\s*)*

no texto que deste como exemplo, devolveria:

{ 1 || Int J Cancer. 2008 May 19; [Epub ahead of print] || PMID: 18491405 [PubMed - as supplied by publisher] } porque cada parágrafo iria estar a ser "gravado" para o mesmo grupo (o 3º). Penso que não exista nenhuma maneira de fazer com que para cada novo parágrafo ele guardasse num grupo diferente a não ser repetindo '([^\n]+)\s*' várias vezes o que não se torna viável 👍

Revolt Website Antigo Nick: Pauzinhos
Link to comment
Share on other sites

Guest id194

Acredita que existe coisas bem mais interessantes para aplicares essa tua curiosidade. Neste exemplo, não ias aprender muito e certamente que não ias descobrir todo o potencial de regex 🙂

@Revolt

Não necessariamente... Bastava ir sacando os parágrafos todos ate descobrir que estamos no próximo paragrafo. Acho que é perfeitamente possível de ser feito, pode é ser complicado e trabalhoso fazer sem erros.

Link to comment
Share on other sites

Guest id194

Talvez tenhas razão, talvez não... Não sei lol, só sei um pouco de regex e não tenho tempo para andar a fazer brincadeiras...

Link to comment
Share on other sites

Pois, foi a esse ponto que cheguei. Teria que ter um padrão tipo ([\d]+: [\s ]+\n) para encontrar o dígito, e daí identificar um novo parágrafo, e depois uma maneira de dizer: encontra todos os possíveis ([[ \n\r\t\w].*\n\n]+). Ou seja, uma classe dentro de uma classe, o que me deu erro 🙂

Enfim, mas o Nazgulled tem razão, apliquei a minha curiosidade a outras coisas e deu frutos 😛 Talvez daqui a uns tempos poste aqui o resultado de todas estas perguntas.

Obrigado a todos, afinal fiquei a saber que até sei brincar um bocadinho com regex, e que isto não era tão simples assim! 👍

Link to comment
Share on other sites

É um bom exercício para o fim de semana :-)

O mais turtuoso é devolver a estrutura de dados que pediste (entretanto, reparei que o código que deixaste não devolve uma estrutura de dados).

Aqui fica um sugestão (em Perl):

NOTA: o que está por baixo de '__DATA__' é este bloco de texto:

__DATA__
1: Int J Cancer. 2008 May 19; [Epub ahead of print]

Statin use and the risk of prostate cancer: A metaanalysis of 6 randomized
clinical trials and 13 observational studies.

Bonovas S, Filioussi K, Sitaras NM.

Department of Pharmacology, School of Medicine, University of Athens, Athens,
Greece.

Statins have been suggested to prevent prostate cancer. Our aim was to examine
of statin use with lower risk of advanced prostate cancer is indeed causal. (c)
2008 Wiley-Liss, Inc.

PMID: 18491405 [PubMed - as supplied by publisher]

2: Int J Cancer. 2008 May 19; [Epub ahead of print]

Statin use and the risk of prostate cancer: A metaanalysis of 6 randomized
clinical trials and 13 observational studies.

Bonovas S, Filioussi K, Sitaras NM.

Department of Pharmacology, School of Medicine, University of Athens, Athens,
Greece.

Statins have been suggested to prevent prostate cancer. Our aim was to examine
of statin use with lower risk of advanced prostate cancer is indeed causal. (c)
2008 Wiley-Liss, Inc.

PMID: 18491405 [PubMed - as supplied by publisher]

3: Int J Cancer. 2008 May 19; [Epub ahead of print]

Statin use and the risk of prostate cancer: A metaanalysis of 6 randomized
clinical trials and 13 observational studies.

Bonovas S, Filioussi K, Sitaras NM.

Department of Pharmacology, School of Medicine, University of Athens, Athens,
Greece.

Statins have been suggested to prevent prostate cancer. Our aim was to examine
of statin use with lower risk of advanced prostate cancer is indeed causal. (c)
2008 Wiley-Liss, Inc.

PMID: 18491405 [PubMed - as supplied by publisher]

#!/usr/bin/perl 
use strict;
use warnings;
use Data::Dumper;

undef $/;
my %parag;
foreach ( split m!(^\d+): |\n{2}!m, <DATA> ) {

    my @linha = do { s!\n! !gm; $_ } if $_ && $_ ne '';
    push @{ $parag{all}}, @linha;

    my $i;
    foreach ( reverse @{ $parag{all} } ) { do { $i = $1; last } if ( /^(\d+)$/ ) }

    push @{ $parag{parag}{$i} }, @linha unless !$linha[0] || $linha[0] =~/^\d+$/gm;
}
print Dumper($parag{parag});

__DATA__
......

E o output:

[me@mybox] $ perl regex_parag.pl
$VAR1 = {
          '1' => [
                   'Int J Cancer. 2008 May 19; [Epub ahead of print]',
                   'Statin use and the risk of prostate cancer: A metaanalysis of 6 randomized clinical trials and 13 observational studies.',
                   'Bonovas S, Filioussi K, Sitaras NM.',
                   'Department of Pharmacology, School of Medicine, University of Athens, Athens, Greece.',
                   'Statins have been suggested to prevent prostate cancer. Our aim was to examine of statin use with lower risk of advanced prostate cancer is indeed causal. (c) 2008 Wiley-Liss, Inc.',
                   'PMID: 18491405 [PubMed - as supplied by publisher]'
                 ],
          '3' => [
                   'Int J Cancer. 2008 May 19; [Epub ahead of print]',
                   'Statin use and the risk of prostate cancer: A metaanalysis of 6 randomized clinical trials and 13 observational studies.',
                   'Bonovas S, Filioussi K, Sitaras NM.',
                   'Department of Pharmacology, School of Medicine, University of Athens, Athens, Greece.',
                   'Statins have been suggested to prevent prostate cancer. Our aim was to examine of statin use with lower risk of advanced prostate cancer is indeed causal. (c) 2008 Wiley-Liss, Inc.',
                   'PMID: 18491405 [PubMed - as supplied by publisher]'
                 ],
          '2' => [
                   'Int J Cancer. 2008 May 19; [Epub ahead of print]',
                   'Statin use and the risk of prostate cancer: A metaanalysis of 6 randomized clinical trials and 13 observational studies.',
                   'Bonovas S, Filioussi K, Sitaras NM.',
                   'Department of Pharmacology, School of Medicine, University of Athens, Athens, Greece.',
                   'Statins have been suggested to prevent prostate cancer. Our aim was to examine of statin use with lower risk of advanced prostate cancer is indeed causal. (c) 2008 Wiley-Liss, Inc.',
                   'PMID: 18491405 [PubMed - as supplied by publisher]'
                 ]
        };

:q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp :quitplease :quitnow :leave ^X^C ^C ^D ^Z ^Q QUITDAMMIT

Link to comment
Share on other sites

Agora é só traduzir a coisa para uma linguagem legível 🙂👍😛

Mas é o equivalente ao que eu fiz em Python. Eu depois acabei por melhorar melhor o meu script para ele dar só o que me interessava, de modo estruturado, ficou assim:

#-*-coding: ISO-8859-15 -*-
# e-Utils scripts
# João Rodrigues

import urllib2
import re

def getAbstracts(alistofids):
    # Get Info
    baseUrl = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&retmode=html&rettype=abstract&id=" # Fetches the articles' info
    
    url = baseUrl+",".join(["%s" % iD for iD in alistofids])
    
    rawResults = urllib2.urlopen(url).read()
    
    regEx = re.compile(r'PMID:.(\d+).\[.*\]')
    
    parsedResults = rawResults.split('\n\n')

    # Organize Results

    linkUrl = "http://www.ncbi.nlm.nih.gov/pubmed/"

    curArticle = {}
    allArticles = []
    bigString = 'a'
    gotTitle = 0
    
    for i in parsedResults[1:]:
        if re.match(regEx, i):
            gotTitle = 0
            curArticle["Title"] = curTitle
            curArticle["Abstract"] = bigString
            curArticle["Link"] = linkUrl+str(re.findall(regEx, i)[0])
            curArticle["PMID"] = str(re.findall(regEx, i)[0])
            allArticles.append(curArticle)
            curArticle = {}
            curTitle = ''
            bigString = ''
        else:
            if len(i) > len(bigString): # Abstract is the biggest
                bigString = i.replace('\n', ' ')
            if gotTitle == 1: # Title is the second from top
                curTitle = i.replace('\n', ' ')
                gotTitle += 1
            else:
                gotTitle += 1

    return allArticles # List of dictionaries with Abstract and Title and Link
Link to comment
Share on other sites

Mas é o equivalente ao que eu fiz em Python.

Não me parece. Repara que eu só atravesso o texto uma vez.

No teu exemplo, a menos que eu esteja a ler mal, percorres duas vezes: 1º fazes o parse do texto para um array e depois percorres o array.

Seria interessante (para mim) que fizesses um dump do resultado, até para perceber o que é que pretendes efectivamente. Entretanto, percebi que aquilo que estás a fazer não é o mesmo que querias quando escreveste o 1º post ;-)

Agora é só traduzir a coisa para uma linguagem legível

Isso não é difícil, afinal de contas são só meia dúzia de linhas.

:q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp :quitplease :quitnow :leave ^X^C ^C ^D ^Z ^Q QUITDAMMIT

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.