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 >
).
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. Imatch()[]
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]
źródło
<>
faktycznie musi być ostatnią rzeczą w ciągu. Jeśli np. Stringfoo <bar> baz
jest dozwolony (i ma dać wynikbar
), 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"
źródło
Prostszy skan to:
String1.scan(/<(\S+)>/).last
źródło