Pobieranie tekstu, który następuje po dopasowaniu wyrażenia regularnego

87

Jestem nowy w używaniu Regex, przeszedłem przez kilka samouczków, ale nie znalazłem takiego, który odnosi się do tego, co chcę robić,

Chcę czegoś wyszukać, ale zwracam wszystko, co następuje, ale nie sam ciąg wyszukiwania

np. „ Jakieś kiepskie zdanie, które jest niesamowite

wyszukaj „ zdanie

powrócić „ to jest niesamowite

Każda pomoc byłaby bardzo mile widziana

Jak dotąd to jest moje wyrażenie regularne

sentence(.*) 

ale zwraca: zdanie, które jest niesamowite

Pattern pattern = Pattern.compile("sentence(.*)");

Matcher matcher = pattern.matcher("some lame sentence that is awesome");

boolean found = false;
while (matcher.find())
{
    System.out.println("I found the text: " + matcher.group().toString());
    found = true;
}
if (!found)
{
    System.out.println("I didn't find the text");
}
Scott
źródło
Jaka jest twoja rzeczywista rozmowa? Czy używasz Matcher?
Grzegorz Oledzki
Używam dopasowywania i wzorca
Scott,
... i nadal chcielibyśmy zobaczyć Twój rzeczywisty kod Java, aby pomóc ocenić, co jest nie tak.
Steve Jorgensen
System.out.println("I found the text: " + "some lame sentance that is aweomse".substring(end()));
Nishant
3
@DavidIsNotHere Nazi powinien mieć duże N ...
Lee Taylor

Odpowiedzi:

141

Możesz to zrobić za pomocą „tylko wyrażenia regularnego”, o które prosiłeś w komentarzu:

(?<=sentence).*

(?<=sentence)jest pozytywnym stwierdzeniem typu lookbehind . To dopasowuje w określonej pozycji w ciągu, a mianowicie w pozycji tuż za tekstem, sentencenie czyniąc samego tekstu częścią dopasowania. W konsekwencji (?<=sentence).*dopasuje dowolny tekst po sentence.

To całkiem fajna funkcja regex. Jednak w Javie będzie to działać tylko dla podwyrażeń o skończonej długości, tj. (?<=sentence|word|(foo){1,4})Jest legalne, ale (?<=sentence\s*)nie jest.

Tim Pietzcker
źródło
Twierdzisz, że nie powinno ono zawierać pozytywnego stwierdzenia „lookbehind”. Więc zakładam, że „. * (? <= Zdanie)” powinno zwracać wszystko do, ale bez „zdania”. Ale tak się nie dzieje, zwraca również „zdanie”. czego mi brakuje?
JJJones_3860
@ user2184214: To dlatego, że jest to spojrzenie za asercję . .*dopasowuje dowolny tekst, a następnie (?<=...)szuka słowa wstecz sentence, stwierdzając w tym przypadku, że dopasowanie kończy się tym słowem. Jeśli chcesz zatrzymać się przed tym słowem, musisz spojrzeć w przyszłość : .*(?=sentence)dopasuje każdy tekst, po którym następuje sentence.
Tim Pietzcker,
17

Twoje wyrażenie regularne "sentence(.*)"ma rację. Aby pobrać zawartość grupy w nawiasach, możesz zadzwonić:

Pattern p = Pattern.compile( "sentence(.*)" );
Matcher m = p.matcher( "some lame sentence that is awesome" );
if ( m.find() ) {
   String s = m.group(1); // " that is awesome"
}

Zwróć uwagę na użycie m.find()w tym przypadku (próby znalezienia dowolnego miejsca w ciągu) i nie m.matches()(nie powiedzie się z powodu przedrostka „jakiś lame”; w tym przypadku regex musiałby być ".*sentence(.*)")

św. nigdy
źródło
Dzięki, ale co, jeśli po prostu chcę, żeby wróciło „to jest niesamowite”
Scott,
Dzięki stary, to zadziałało świetnie, miałem nadzieję, że można to zrobić za pomocą samego wyrażenia regularnego, jeśli nie mogę znaleźć sposobu, aby to zrobić w ten sposób, to również zadziała
Scott
Prawdopodobnie zły pomysł, aby dodać „(. *)” Na końcu
wyrażenia regularnego
8

jeśli Matcher jest zainicjowany str, to po dopasowaniu możesz otrzymać część po dopasowaniu za pomocą

str.substring(matcher.end())

Przykładowy kod:

final String str = "Some lame sentence that is awesome";
final Matcher matcher = Pattern.compile("sentence").matcher(str);
if(matcher.find()){
    System.out.println(str.substring(matcher.end()).trim());
}

Wynik:

to jest niesamowite

Sean Patrick Floyd
źródło
matcher.find()jest wymagana wcześniej, IMO.
Nishant,
@Nishant tak napisałem: „po meczu”. Dodano przykładowy kod do zilustrowania
Sean Patrick Floyd
1

Musisz użyć grupy (int) swojego dopasowania - grupa (0) to cały mecz, a grupa (1) to pierwsza zaznaczona grupa. W podanym przykładzie grupa (1) występuje po wyrażeniuzdanie ”.

Rami C
źródło
1

Wystarczy, że w poniższym wierszu wpiszesz „group (1)” zamiast „group ()”, a wynik będzie zgodny z oczekiwaniami:

System.out.println("I found the text: " + matcher.group(**1**).toString());
Ricardo Ferreira
źródło