Obecnie próbuję przekształcić ciąg na wiele zmiennych. Przykładowy ciąg:
ryan_string = "RyanOnRails: This is a test"
Dopasowałem to do tego wyrażenia regularnego z trzema grupami:
ryan_group = ryan_string.scan(/(^.*)(:)(.*)/i)
Teraz, aby uzyskać dostęp do każdej grupy, muszę zrobić coś takiego:
ryan_group[0][0] (first group) RyanOnRails
ryan_group[0][1] (second group) :
ryan_group[0][2] (third group) This is a test
Wydaje się to dość śmieszne i wydaje mi się, że robię coś złego. Spodziewałbym się, że będę mógł zrobić coś takiego:
g1, g2, g3 = ryan_string.scan(/(^.*)(:)(.*)/i)
czy to możliwe? A może jest lepszy sposób niż to, jak to robię?
źródło
one, two, three = string.match(/(^.*)(:)(.*)/i).captures
na:one, two, three = string.match(/(^.*)(:)(.*)/i).try(:captures)
&.
operator, aby przywrócić go do linii, a nawet użyć go dwukrotnie, gdy jest tylko jedna grupa przechwytywania. Np. ...,string.match(regex)&.captures&.first
Możesz zamiast tego użyć Match lub = ~, co da ci jedno dopasowanie i możesz albo uzyskać dostęp do danych dopasowania w ten sam sposób, albo po prostu użyć specjalnych zmiennych dopasowania $ 1, $ 2, $ 3
Coś jak:
źródło
Możesz nazwać przechwycone mecze
Nie działa, jeśli odwrócisz kolejność ciągów i wyrażeń regularnych.
źródło
Musisz zdecydować, czy to dobry pomysł, ale wyrażenie regularne Ruby może (automagicznie) definiować zmienne lokalne za Ciebie!
Nie jestem jeszcze pewien, czy ta funkcja jest niesamowita, czy po prostu całkowicie szalona, ale twoje wyrażenie regularne może definiować zmienne lokalne.
(Spójrz na http://ruby-doc.org/core-2.1.1/Regexp.html , wyszukaj „zmienna lokalna”).
Uwaga: Jak wskazano w komentarzu, widzę, że istnieje podobna i wcześniejsza odpowiedź na to pytanie od @toonsend ( https://stackoverflow.com/a/21412455 ). Chyba nie „kradłem”, ale jeśli chcesz być uczciwy w pochwałach i uhonorować pierwszą odpowiedź, nie krępuj się :) Mam nadzieję, że żadne zwierzęta nie zostały skrzywdzone.
źródło
scan()
znajdzie wszystkie nienakładające się dopasowania wyrażenia regularnego w twoim ciągu, więc zamiast zwracać tablicę twoich grup, jak się wydaje, że się spodziewasz, zwraca tablicę tablic.Prawdopodobnie lepiej będzie, jeśli użyjesz
match()
, a następnie uzyskasz tablicę przechwytywania za pomocąMatchData#captures
:Jednak możesz to również zrobić,
scan()
jeśli chcesz:źródło