2013-01-08 24 views
6

Czy ktoś mógłby wyjaśnić różnicę między .+ i .+?Różnica między ". +" I ". +?"

Mam ciąg: "extend cup end table"

  1. Wzorzec e.+d znaleziska: extend cup end
  2. Wzór e.+?d stwierdzenia: extend i end

Wiem, że + to jeden lub więcej, a ? to jeden lub zero. Ale nie jestem w stanie zrozumieć, jak to działa.

+0

Jak wspomniano poniżej, różnica między chciwymi a leniwymi kwantyfikatorami. Chciwy chcą konsumować jak najwięcej, leniwy jak najmniej. Silnik będzie "budował ciąg" znaków po znaku, od lewej do prawej, kiedy kwantyfikator jest leniwy. Chciwy zrobi coś przeciwnego.Spowoduje to zużycie w miarę możliwości, a następnie upuszczenie kilku znaków, od prawej do lewej, jeśli zajdzie taka potrzeba. Zobacz następujące przykłady: http://regex101.com/r/dG9zZ2 i http://regex101.com/r/tP5xQ3 –

Odpowiedz

16

Obie odpowiadają dowolnej sekwencji jednego lub więcej znaków. Różnica polega na tym, że:

  • .+ jest chciwy i zużywa tyle znaków, ile to możliwe.
  • .+? jest niechętny i konsumuje jak najmniej znaków, jak tylko może.

Zobacz samouczek języka Java, zobacz Differences Among Greedy, Reluctant, and Possessive Quantifiers.

Zatem:

  • e.+d znajdzie najdłuższy podciąg, który zaczyna się i kończy z ed (i zawiera co najmniej jeden znak pomiędzy).
  • znajdź najkrótszy taki podciąg. W twoim przykładzie, extend i end są dwoma takimi nienakładającymi się dopasowaniami, więc znajduje obie.
+0

Po prostu przetestowałem wyrażenia na rubular.com, a ja właściwie jestem nieco zakłopotany, dlaczego dodawanie? sprawia, że ​​wyrażenie ignoruje "kubek". Twoja odpowiedź tak naprawdę nie wyjaśnia tego w szczegółach. Czy byłoby możliwe dodanie do tego linii lub dwóch? – Henrik

+0

@Henrik Rezultat był podobny do tego w pytaniu, w oryginalnym pytaniu było dziwne formatowanie, którego nie udało się poprawnie edytować przy pierwszej próbie – Kapep

5

regex e.+?d dopasowuje 'e' a następnie stara się dopasować jak kilka znaków, jak to możliwe (ungreedy lub niechętnie), a następnie przez 'd'. Dlatego poniższe 2 podciągi są dopasowane:

extend cup end table 
^^^^^^  ^^^ 
    1   2 

regex e.+d dopasowuje 'e' a następnie próbuje dopasować tyle znaków, jak to możliwe (chciwy), a następnie przez 'd'. Co się dzieje, jest to, że pierwszy 'e' zostanie znaleziony, a następnie .+ mecze jak to możliwe (do końca linii, lub wejście):

extend cup end table 
^^^^^^^^^^^^^^^^^^^^ 

Silnik regex dochodzi do końca wiersza (lub wejście) i nie może dopasować 'd' do wzorca regex. W ten sposób następuje powrót do ostatniej 'd' piły. Dlatego znaleziono pojedynczy mecz:

extend cup end table 
^^^^^^^^^^^^^^<----- backtrack 
    1