示例输入:
2018-09-28 00:00:01 INFO .....
2018-09-28 00:00:01 INFO tx=1111 ....
2018-09-28 00:00:01 INFO - Invoking API time=515ms
-> Invoked URL: 'http://........'
-> Authorization: ....
-> Request: blah blah request
<- Response: 201 - Success
我想为每个响应获取tx = 1111:201
可以这样做吗?我可以使用正向回溯吗?
答案 0 :(得分:0)
我将使用regexp,然后过滤结果:
input.
scan(/(tx=\d+).*?Response:\s+(\d+)/m).
select { |_, resp| resp == '201' }.
map(&:first)
#⇒ ["tx=1111"]
答案 1 :(得分:0)
假设字符串如下。
str =<<BITTER_END
2018-09-28 00:00:01 INFO .....
2018-09-28 00:00:01 INFO tx=1111 ....
2018-09-28 00:00:01 INFO - Invoking API time=515ms
-> Invoked URL: 'http://........'
-> Authorization: ....
-> Request: blah blah request
<- Response: 201 - Success
2018-09-28 00:00:01 INFO .....
2018-09-28 00:00:01 INFO tx=1112 ....
2018-09-28 00:00:01 INFO - Invoking API time=515ms
-> Invoked URL: 'http://........'
-> Authorization: ....
-> Request: blah blah request
<- Response: 202 - Success
2018-09-28 00:00:01 INFO .....
2018-09-28 00:00:01 INFO tx=1113 ....
2018-09-28 00:00:01 INFO - Invoking API time=515ms
-> Invoked URL: 'http://........'
-> Authorization: ....
-> Request: blah blah request
<- Response: 201 - Success
BITTER_END
我的理解是,我们希望在tx
之后(几行之后)返回<- Response: 201
的值(数组)。如果正确,我们希望返回["1111", "1113"]
,但不返回"1112"
,因为后面跟着<- Response: 202
。
如果我们首先反转字符串,使它显示如下(puts str.reverse
的结果),则可以使用简单的正则表达式来完成。
sseccuS - 102 :esnopseR -<
tseuqer halb halb :tseuqeR >-
.... :noitazirohtuA >-
'........//:ptth' :LRU dekovnI >-
sm515=emit IPA gnikovnI - OFNI 10:00:00 82-90-8102
.... 3111=xt OFNI 10:00:00 82-90-8102
..... OFNI 10:00:00 82-90-8102
sseccuS - 202 :esnopseR -<
tseuqer halb halb :tseuqeR >-
.... :noitazirohtuA >-
'........//:ptth' :LRU dekovnI >-
sm515=emit IPA gnikovnI - OFNI 10:00:00 82-90-8102
.... 2111=xt OFNI 10:00:00 82-90-8102
..... OFNI 10:00:00 82-90-8102
sseccuS - 102 :esnopseR -<
tseuqer halb halb :tseuqeR >-
.... :noitazirohtuA >-
'........//:ptth' :LRU dekovnI >-
sm515=emit IPA gnikovnI - OFNI 10:00:00 82-90-8102
.... 1111=xt OFNI 10:00:00 82-90-8102
..... OFNI 10:00:00 82-90-8102
我们的正则表达式如下。
r = /
[ ]102[ ]:esnopseR[ ]-< # match reverse of `'<- Response: 201'
.+? # match one or more characters, lazily
[ ] # match a space
(\d+) # match one or more digits in capture group 1
=xt[ ][ ]OFNI # match '=xt OFNI'
/xm # free-spacing and multiline modes
(我已经在自由空间模式下编写了它,以便记录每个元素。) 1 然后我们可以使用String#scan提取所需的值。
str.reverse.scan(r).flatten.map(&:reverse).reverse
#=> ["1111", "1113"]
我们首先获得以下内容。
str.reverse.scan(r)
#=> [["3111"], ["1111"]]
根据需要["1111", "1113"]
,我们必须展平此数组,反转每个字符串,然后反转反转的字符串的顺序。
1。该正则表达式通常用/ 102 :esnopseR -<.+? (\d+)=xt OFNI/m
表示。在自由间距模式下删除空格,这就是为什么使用/x
选项时每个空格都包含在字符类中的原因。为了最大程度地减少错误,最好写/#{'<- Response: 201 '.reverse}.+? (\d+)#{'INFO tx='.reverse}/m
。