Как вернуть подстроку строки между двумя строками в Ruby? - PullRequest
35 голосов
/ 12 марта 2012

Как бы я возвратил строку между двумя строковыми маркерами строки в Ruby?

Например, у меня есть:

  • input_string
  • str1_markerstring
  • str2_markerstring

Хотите сделать что-то вроде:

input_string.string_between_markers(str1_markerstring, str2_markerString)

Пример текста:

1.9.3-p0 :020 >   s
 => "Charges for the period 2012-01-28 00:00:00 to 2012-02-27 23:59:59:<br>\nAny Network Cap remaining: $366.550<br>International Cap remaining: $0.000"
1.9.3-p0 :021 > str1_markerstring
 => "Charges for the period"
1.9.3-p0 :022 > str2_markerstring
 => "Any Network Cap"
1.9.3-p0 :023 > s[/#{str1_markerstring}(.*?)#{str2_markerstring}/, 1]
 => nil  # IE DIDN'T WORK IN THIS CASE

Ответы [ 3 ]

76 голосов
/ 12 марта 2012
input_string = "blahblahblahSTARTfoofoofooENDwowowowowo"
str1_markerstring = "START"
str2_markerstring = "END"

input_string[/#{str1_markerstring}(.*?)#{str2_markerstring}/m, 1]
#=> "foofoofoo"

или в методе:

class String
  def string_between_markers marker1, marker2
    self[/#{Regexp.escape(marker1)}(.*?)#{Regexp.escape(marker2)}/m, 1]
  end
end

"blahblahblahSTARTfoofoofooENDwowowowowo".string_between_markers("START", "END")
#=> "foofoofoo"
5 голосов
/ 01 ноября 2018

Просто разделите его дважды и получите строку между маркерами:

input_string.split("str1_markerstring").last.split("str2_markerstring").first
0 голосов
/ 11 марта 2016

Вот несколько альтернативных способов сделать то, что вы хотите, вот как я бы это сделал:

s = "Charges for the period 2012-01-28 00:00:00 to 2012-02-27 23:59:59:<br>\nAny Network Cap remaining: $366.550<br>International Cap remaining: $0.000"  # => "Charges for the period 2012-01-28 00:00:00 to 2012-02-27 23:59:59:<br>\nAny Network Cap remaining: $366.550<br>International Cap remaining: $0.000"

dt1, dt2 = /period (\S+ \S+) to (\S+ \S+):/.match(s).captures  # => ["2012-01-28 00:00:00", "2012-02-27 23:59:59"]
dt1                                                            # => "2012-01-28 00:00:00"
dt2                                                            # => "2012-02-27 23:59:59"

Это использует «period» и «to» и трейлинг «:», чтобы пометитьначало и конец диапазона, который нужно найти, и захват непробельных символов, которые обозначают дату и время в каждой метке даты и времени.

Альтернативно, использование «named-captures» предопределяет переменные:

/period (?<dt1>\S+ \S+) to (?<dt2>\S+ \S+):/ =~ s  # => 16
dt1                                                # => "2012-01-28 00:00:00"
dt2                                                # => "2012-02-27 23:59:59"

С этого момента, если вы хотите разбить возвращаемые значения, вы можете проанализировать их как даты:

require 'date'
d1 = DateTime.strptime(dt1, '%Y-%m-%d %H:%M:%S')  # => #<DateTime: 2012-01-28T00:00:00+00:00 ((2455955j,0s,0n),+0s,2299161j)>
d1.month                                          # => 1
d1.day                                            # => 28

Или вы можете даже использовать вспомогательные снимки:

matches = /period (?<dt1>(?<date1>\S+) (?<time1>\S+)) to (?<dt2>(?<date2>\S+) (?<time2>\S+)):/.match(s)
matches # => #<MatchData "period 2012-01-28 00:00:00 to 2012-02-27 23:59:59:" dt1:"2012-01-28 00:00:00" date1:"2012-01-28" time1:"00:00:00" dt2:"2012-02-27 23:59:59" date2:"2012-02-27" time2:"23:59:59">
matches['dt1']   # => "2012-01-28 00:00:00"
matches['date1'] # => "2012-01-28"
matches['time2'] # => "23:59:59"

Все это документировано в документации Regexp .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...