2011-01-11 13 views
268

Mam ciąg znaków, który ma dwa pojedyncze cudzysłowy, znak '. Pomiędzy pojedynczymi cytatami są dane, które chcę.Jak wyodrębnić podciąg używając regex

Jak napisać wyrażenie regularne, aby wyodrębnić "dane, które chcę" z poniższego tekstu?

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

Odpowiedz

405

Zakładając chcesz udział między apostrofami, należy użyć tego wyrażenia regularnego z Matcher:

"'(.*?)'" 

Przykład:

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)); 
} 

Wynik:

 
the data i want 
+9

cholera .. I zawsze zapomnieć o braku chciwy modyfikatora :( –

+20

zastąpić "czy" z "a", kiedy można oczekiwać więcej niż jeden occurences – OneWorld

+10

umysł to matcher.find() jest potrzebne, aby ten przykład kodu działał, a niepowodzenie wywołania tej metody spowoduje, że zostanie wywołany wyjątek "No match found", gdy wywoływany jest matcher.group (1) . – rexford

3

jak w javascript:

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

rzeczywista regexp jest: /'([^']+)'/

jeśli używasz non zachłanny modyfikator (jak w innym poście) to tak:

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

jest czystszy.

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.group (0)); <--- Indeks zerowy – nclord

+1

Nr grupy (0) ma specjalne znaczenie, przechwytywanie grup rozpoczyna się od grupy indeksu (1) (tj. Grupa (1) jest poprawna w odpowiedzi). "Grupy przechwytywania są indeksowane od lewej do prawej, zaczynając od 1. Grupa zero oznacza cały wzorzec" - Źródło: https://docs.oracle.com/javase/8/docs/api/java/util/regex/ Matcher.html # group-int- – Apriori

+0

Użyłem grupy (1), ale nie uzyskałem żadnego wyniku ... –

8

ponieważ ty także Ticked Scala, rozwiązanie bez regex który łatwo zajmuje się wieloma cudzysłowami:

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

Sprytny. Pokochałem to. –

+3

Czytelne rozwiązanie, to dlatego ludzie uwielbiają scala, którą wierzę :) – prayagupd

+2

Dlaczego po prostu '.split ('\' '). Get (2)' lub coś w tym zakresie w Javie? Myślę, że możesz potrzebować wykonać skanowanie mózgu, jeśli uważasz, że jest to czytelne rozwiązanie - wygląda na to, że ktoś próbował zrobić dla mnie jakiś kod golfowy. – ArtOfWarfare

2

w 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

Nie trzeba do tego wyrażenia regularnego.

Dodaj Apache Commons Lang do projektu (http://commons.apache.org/proper/commons-lang/), a następnie użyć:

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

dziękuję ..... jestem początkującym, by wyrecytować ... więc myślę, że to jest łatwy sposób ... –

+63

Nie, powinieneś używać wyrażeń regularnych. To okropne wzdęcie, aby dodać całą dużą zależność do projektu dla tej prostej funkcjonalności. Naucz się regex, będziesz go używać w kółko w swojej karierze. – BadZen

+9

Należy wziąć pod uwagę sposób dystrybucji oprogramowania. Jeśli jest to coś w rodzaju webstartu, nie jest mądre dodawanie wspólnych serwerów Apache tylko do korzystania z tej jednej funkcji. Ale może tak nie jest. Oprócz Apache commons ma wiele więcej do zaoferowania. Nawet jeśli dobrze jest znać regex, musisz zachować ostrożność, kiedy go używać. Regex może być naprawdę trudny w czytaniu, pisaniu i debugowaniu. Biorąc pod uwagę pewien kontekst z wykorzystaniem tego może być lepszym rozwiązaniem. – Beothorn

3

Jest prosta-liner na to:

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

Dokonując grupa dopasowanie opcjonalne, to również dba o to, aby nie znaleziono ofert przez zwrócenie pustego miejsca w tym przypadku.

Zobacz live demo.

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

Proszę wyjaśnić swój kod. – bfontaine

Powiązane problemy