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

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.


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(.*)")


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


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 ”.


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());
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.