2011-01-11 23 views
268

Ich habe eine Zeichenfolge, die zwei einfache Anführungszeichen enthält, das ' Zeichen. Zwischen den einzelnen Anführungszeichen stehen die Daten, die ich haben möchte.Wie extrahiere ich einen Teilstring mit Regex

Wie kann ich eine Regex schreiben, um "die Daten, die ich will" aus dem folgenden Text zu extrahieren?

mydata = "some string with 'the data i want' inside"; 

Antwort

405

Angenommen, Sie den Teil zwischen einfachen Anführungszeichen möchten, verwenden Sie diesen regulären Ausdruck mit einem Matcher:

"'(.*?)'" 

Beispiel:

String mydata = "some string with 'the data i want' inside"; 
Pattern pattern = Pattern.compile("'(.*?)'"); 
Matcher matcher = pattern.matcher(mydata); 
if (matcher.find()) 
{ 
    System.out.println(matcher.group(1)); 
} 

Ergebnis:

 
the data i want 
+9

verdammt sehen .. ich immer über die nicht gierig Modifikator vergessen :( –

+20

ersetzen die „if“ mit einem „während“, wenn Sie mehr als ein Vorkommen erwarten – OneWorld

+10

Geist matcher.find() wird benötigt, damit dieses Codebeispiel funktioniert Wenn diese Methode nicht aufgerufen wird, wird beim Aufruf von matcher.group (1) die Ausnahme "Keine Übereinstimmung gefunden" angezeigt. – rexford

3

wie in javascript:

mydata.match(/'([^']+)'/)[1] 

die tatsächliche regexp ist: /'([^']+)'/

wenn Sie die nicht gierig Modifikator (gemäß einem anderen Beitrag) ist es wie folgt aus:

mydata.match(/'(.*?)'/)[1] 

es ist sauberer.

9
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class Test { 
    public static void main(String[] args) { 
     Pattern pattern = Pattern.compile(".*'([^']*)'.*"); 
     String mydata = "some string with 'the data i want' inside"; 

     Matcher matcher = pattern.matcher(mydata); 
     if(matcher.matches()) { 
      System.out.println(matcher.group(1)); 
     } 

    } 
} 
+2

System.out.println (Matcher-Gruppe (0)); <--- Nullbasierter Index – nclord

+1

Nr. Gruppe (0) hat eine besondere Bedeutung, die Erfassungsgruppen beginnen bei Indexgruppe (1) (d. H. Gruppe (1) ist in der Antwort korrekt). "Erfassende Gruppen werden von links nach rechts indiziert, beginnend bei eins. Gruppe Null bezeichnet das gesamte Muster" - Quelle: https://docs.oracle.com/javase/8/docs/api/java/util/regex/ Matcher.html # group-int- – Apriori

+0

Ich habe Gruppe (1) verwendet, aber habe kein Ergebnis erhalten ... –

8

Weil Du auch tickte Scala, eine Lösung ohne Regex, die mit mehreren Strings in Anführungszeichen behandelt leicht:

val text = "some string with 'the data i want' inside 'and even more data'" 
text.split("'").zipWithIndex.filter(_._2 % 2 != 0).map(_._1) 

res: Array[java.lang.String] = Array(the data i want, and even more data) 
+0

Clever. Liebte es. –

+3

So lesbare Lösung, deshalb Menschen lieben scala ich glaube :) – prayagupd

+2

Warum nicht einfach '.split ('\' '). Get (2)' oder etwas in diesem Umfang in Java? Ich denke, dass Sie möglicherweise einen Gehirn-Scan bekommen müssen, wenn Sie denken, dass das eine lesbare Lösung ist - es sieht so aus, als ob jemand versucht hätte, Code-Golf zu spielen. – ArtOfWarfare

2

In Scala,

val ticks = "'([^']*)'".r 

ticks findFirstIn mydata match { 
    case Some(ticks(inside)) => println(inside) 
    case _ => println("nothing") 
} 

for (ticks(inside) <- ticks findAllIn mydata) println(inside) // multiple matches 

val Some(ticks(inside)) = ticks findFirstIn mydata // may throw exception 

val ticks = ".*'([^']*)'.*".r  
val ticks(inside) = mydata // safe, shorter, only gets the first set of ticks 
53

Sie brauchen nicht Regex für diese.

hinzufügen Apache Commons lang zu einem Projekt (http://commons.apache.org/proper/commons-lang/), dann verwenden:

String dataYouWant = StringUtils.substringBetween(mydata, "'"); 
+0

danke ..... ich bin Neuling zu Regex ... so denke ich, das ist einfacher Weg .... –

+63

Nein, Sie sollten Regex verwenden. Es ist eine schreckliche Bloat, eine große Abhängigkeit zu Ihrem Projekt für diese einfache Funktionalität hinzuzufügen. Lerne Regex, du wirst es in deiner Karriere immer wieder benutzen. – BadZen

+9

Sie müssen berücksichtigen, wie Ihre Software verteilt wird. Wenn es sich um einen Webstart handelt, ist es nicht ratsam, Apache commons nur hinzuzufügen, um diese eine Funktion zu verwenden. Aber vielleicht ist es nicht. Außerdem hat Apache Commons viel mehr zu bieten. Auch wenn es gut ist, Regex zu kennen, muss man vorsichtig sein, wenn man es benutzt. Regex kann wirklich schwer zu lesen, zu schreiben und zu debuggen sein. Bei gegebenem Kontext könnte dies die bessere Lösung sein. – Beothorn

3

Es gibt einen einfachen Einzeiler hierfür:

String target = myData.replaceAll("[^']*(?:'(.*?)')?.*", "$1"); 

die passende Gruppe optional Indem dies auch sorgt dafür, dass Zitate nicht gefunden werden, indem in diesem Fall ein Leerzeichen zurückgegeben wird.

Siehe live demo.

1
String dataIWant = mydata.replaceFirst(".*'(.*?)'.*", "$1"); 
+1

Bitte erläutern Sie Ihren Code. – bfontaine

Verwandte Themen