2013-05-25 23 views
9

Sto provando a scrivere un'espressione regolare in Java per trovare il contenuto tra virgolette singole. Mi può aiutare per favore con questo? Ho provato quanto segue, ma non funziona in alcuni casi:Java regex il contenuto tra virgolette singole

Pattern p = Pattern.compile("'([^']*)'"); 
  1. Test Case: 'Tumblr' è una produzione sorprendente app atteso: Tumblr

  2. Test Case : Tumblr è una straordinaria 'app' Uscita prevista: app

  3. Test Case: Tumblr è un 'incredibile' applicazione Previsto in uscita: stupefacente

  4. Test Case: Tumblr è 'impressionante' e 'sorprendente' uscita prevista: impressionante, straordinaria

  5. test Case: utenti di Tumblr sono delusi previsto in uscita: NONE

  6. Test Case: Tumblr di 'acquisizione' dubbioso uscita prevista completa ma la fedeltà degli utenti: acquisizione

Apprezzo tutto l'aiuto con questo.

Grazie.

+0

C'è non c'è bisogno di forzare gli spazi vuoti all'interno delle virgolette (il che renderà _'awesone e amazing'_ non corrispondente), puoi solo guardare le virgolette. –

risposta

12

Questo dovrebbe fare il trucco:

(?:^|\s)'([^']*?)'(?:$|\s) 

Esempio: http://www.regex101.com/r/hG5eE1

In Java (ideone):

import java.util.*; 
import java.lang.*; 
import java.util.regex.*; 

class Main { 

     static final String[] testcases = new String[] { 
      "'Tumblr' is an amazing app", 
     "Tumblr is an amazing 'app'", 
     "Tumblr is an 'amazing' app", 
     "Tumblr is 'awesome' and 'amazing' ", 
     "Tumblr's users' are disappointed ", 
     "Tumblr's 'acquisition' complete but users' loyalty doubtful" 
     }; 

    public static void main (String[] args) throws java.lang.Exception { 
     Pattern p = Pattern.compile("(?:^|\\s)'([^']*?)'(?:$|\\s)", Pattern.MULTILINE); 
     for (String arg : testcases) { 
      System.out.print("Input: "+arg+" -> Matches: "); 
      Matcher m = p.matcher(arg); 
      if (m.find()) { 
       System.out.print(m.group()); 
       while (m.find()) System.out.print(", "+m.group()); 
       System.out.println(); 
      } else { 
       System.out.println("NONE"); 
      } 
     } 
    } 
} 
+0

Mi sono reso conto che la tua risposta è più solida in quanto ho testato più scenari. Vorrei avere abbastanza reputazione per revocare la risposta. – user1744332

+0

non è davvero completo perché le virgolette singole fanno parte dell'output ;-). Potrebbe essere corretto con m.group(). Replace ('\' ',' \ u0000 ') – dermoritz

+0

@dermoritz non ne ha bisogno; la stessa regex catturerà la stringa con le virgolette nel gruppo (0) e senza virgolette nel gruppo (1). http://ideone.com/m9t1AF –

0

Provate questo semplice schema di espressione regolare:

'([^\s']+)' 

e un codice di prova:

try { 
    Pattern regex = Pattern.compile("'([^\\s']+)'"); 
    Matcher regexMatcher = regex.matcher(subjectString); 
    while (regexMatcher.find()) { 
     for (int i = 1; i <= regexMatcher.groupCount(); i++) { 
      // matched text: regexMatcher.group(i) 
      // match start: regexMatcher.start(i) 
      // match end: regexMatcher.end(i) 
     } 
    } 
} catch (PatternSyntaxException ex) { 
    // Syntax error in the regular expression 
} 
0

Basta non lasciare che ' ' appaiono nell'output. Utilizzare questa espressione regolare:

'([^' ]*)'

Oppure assicurarsi che la coppia di preventivo sia avvolta da spazi.

(?:^|)'([^']*)'(?: |$)
+0

Questo non corrisponderà a "..." sorprendente e bello "..." –

+0

@guido Prova la nuova soluzione. – johnchen902

+0

meglio, ma hai ancora spazio invece di spazi bianchi, e non ottiene fine riga (quindi è come il mio ;-) –

3

Se non si consente il singolo carattere preventivo, ', o il carattere di spazio, ' ', di essere nel modello, allora sei a posto.Ho usato + perché davo per scontato che non vuoi una voce vuota (se non, cambiarlo di nuovo ad un *):

Pattern p = Pattern.compile("'([^' ]+)'"); 
+0

Questo funziona per l'input, difficile notare che Paul Vargas e il mio pattern accetterebbero anche spazi bianchi all'interno della stringa abbinata. –

+0

Sono d'accordo; le tue soluzioni sono buone e sensate, ma nessuno degli input di esempio ha suggerito che l'OP voleva catturare più parole, quindi nel tentativo di tenerlo il più vicino possibile al codice/restrizioni dell'OP, mi è venuto in mente questo. –

+0

si. Sono d'accordo con @guido. – user1744332

1

provare il prossimo:

'\w+'|'\w+(\s\w+)*' 

https://github.com/paul-vargas/java-regex-ui