2011-01-04 23 views
6

Attualmente sto cercando di eliminare acronmys da un gruppo di documenti.Espressione regolare per acronimi

dicono che il documento contiene "Static test di sicurezza delle applicazioni (SAST)"

Così sto cercando di creare una regex per filtrare questo tipo di stringhe. Probabilmente dovrebbe essere qualcosa come

"un numero di parole la cui lettera iniziale viene successivamente ripetuta nelle parentesi".

Sfortunatamente la mia regex non è molto buona per formulare questo. Credi che si possa fare tramite regex o ho bisogno di qualcosa di più potente come un parser basato su CFG?

+0

Che lingua? Questo può essere un po 'divertente regex in. Net, ma non sono sicuro che Java possa gestirlo. La risposta generale è che non è possibile utilizzare una regex, ma ** estremamente facile ** da eseguire manualmente eseguendo il ciclo tra le parole, non è davvero necessario un parser. – Kobi

+3

Anche se la regex può fare ciò, non sono sicuro che * appartenga * al dominio best-done-via-regex. Vedi [Per utilizzare o non usare espressioni regolari?] (Http://stackoverflow.com/questions/4098086/to-use-or-not-to-use-regular-expressions/4098123#4098123). Trovare un numero di parole seguite da una sequenza di lettere maiuscole a tutto spazio in Parens è facile e meglio-via-regex. – delnan

+0

Yikes, la prima volta che ho letto questo messaggio mi è stato erroneamente annotato * anagramma * per * acronimo *! Non so che le regex siano del tutto inopportune per * gli acronimi * - la soluzione offerta sembra piuttosto semplice - ma usarne una per generare * anagrammi * equivarrebbe a implementare contrappunto polifonico su uno strumento intrinsecamente a thread singolo come il violino. Dovresti essere pazzo, o un vero maestro, perfino tentare di farlo (* viz.* BWV 1001-1006). – tchrist

risposta

3

Prova questo (per 2 acronimi lettera):

\b(\w)\w+\s+\b(\w)\w+\s+\(\1\2\) 

questo per 3 lettera acronimi:

\b(\w)\w+\s+\b(\w)\w+\s+\b(\w)\w+\s+\(\1\2\3\) 

Questo per 4 lettera acronimi:

\b(\w)\w+\s+\b(\w)\w+\s+\b(\w)\w+\s+\b(\w)\w+\s+\(\1\2\3\4\) 

Si prega di notare che il l'espressione regolare deve essere insensibile alle maiuscole/minuscole.

BTW il Regex Coach è uno strumento utile per provare cose del genere.

+0

Abbastanza intelligente. +1 – Kobi

+0

Lo controllerò. Ho gli strumenti di regular-expressions.info qui. Non ho ancora speso molte cellule cerebrali sull'intera questione. – er4z0r

1

Ecco due soluzioni Perl: il primo va parola per parola, costruisce un array creato dal primo leter di ogni parola, quindi rimuove l'acronimo formato da quei leters. È abbastanza debole, e dovrebbe fallire se c'è più che l'acronimo e le lettere per riga - Utilizza anche il pattern (?? {}) per inserire l'acronimo nella regex, il che mi fa nausea:

use strict; 
use warnings; 
use 5.010; 

$_ = "Static application security testing (SAST)"; 

my @first; 
s/ 
    \b 
    (?<first>\p{L})\p{L}* 
    \b 
(?{ push @first, $+{first} }) 
    \K \s+ \(
    (??{ join '', map { uc } @first; }) 
    \) 
//gx; 

say; 

Nel frattempo, questa soluzione controlla innanzitutto qualcosa di simile a un acronimo, quindi costruisce un'espressione regolare per abbinare il numero di parole necessarie: $ _ = "Test di sicurezza delle applicazioni statiche (SAST)";

my ($possible_acronym) = /\((\p{Lu}+)\)/; 
my $regex = join '', map({ qr/\b(?i:$_)\p{L}*\b\s*?/ } split //, $possible_acronym), qr/\K\Q($possible_acronym)/; 
s/$regex//; 

say; 

(ho provato a fare una soluzione che utilizza (? (DEFINIRE)) modelli, come la risposta di tchrist here, ma fallì miseramente. Vabbè.)

Per di più su (? :), cattura di nome (?), \ K, e un sacco di roba magica, perlre è la risposta.