Jak mogę wyodrębnić podciąg z ciągu w Rubim?
Przykład:
String1 = "<name> <substring>"
Chcę wyodrębnić substring
z String1
(tj. Wszystko w ostatnim wystąpieniu <
i >
).
Jak mogę wyodrębnić podciąg z ciągu w Rubim?
Przykład:
String1 = "<name> <substring>"
Chcę wyodrębnić substring
z String1
(tj. Wszystko w ostatnim wystąpieniu <
i >
).
Odpowiedzi:
String1.scan(/<([^>]*)>/).last.first
scan
tworzy tablicę, która dla każdego <item>
in String1
zawiera tekst między znakami <
a >
w tablicy jednoelementowej (ponieważ w przypadku użycia z wyrażeniem regularnym zawierającym grupy przechwytywania, scan tworzy tablicę zawierającą przechwycenia dla każdego dopasowania). last
daje ci ostatnią z tych tablic, a first
następnie daje ci ciąg w niej.
"<name> <substring>"[/.*<([^>]*)/,1]
=> "substring"
Nie ma potrzeby używania scan
, jeśli potrzebujemy tylko jednego wyniku.
Nie ma potrzeby używania Pythona match
, skoro mamy Rubiego String[regexp,#]
.
Zobacz: http://ruby-doc.org/core/String.html#method-i-5B-5D
Uwaga: str[regexp, capture] → new_str or nil
if we need only one result
w moim rozwiązaniu. I match()[]
jest wolniejszy, ponieważ to dwie metody zamiast jednej.
string[regex]
w tym scenariuszu może być równie czytelny, więc tego właśnie użyłem osobiście.
Możesz łatwo użyć wyrażenia regularnego…
Zezwalanie na spacje wokół słowa (ale ich nie zachowywanie):
str.match(/< ?([^>]+) ?>\Z/)[1]
Lub bez dozwolonych spacji:
str.match(/<([^>]+)>\Z/)[1]
<>
faktycznie musi być ostatnią rzeczą w ciągu. Jeśli np. String foo <bar> baz
jest dozwolony (i ma dać wynik bar
), to nie zadziała.
Oto nieco bardziej elastyczne podejście przy użyciu tej match
metody. Dzięki temu możesz wyodrębnić więcej niż jeden ciąg:
s = "<ants> <pants>"
matchdata = s.match(/<([^>]*)> <([^>]*)>/)
# Use 'captures' to get an array of the captures
matchdata.captures # ["ants","pants"]
# Or use raw indices
matchdata[0] # whole regex match: "<ants> <pants>"
matchdata[1] # first capture: "ants"
matchdata[2] # second capture: "pants"