是文件路径且包含特殊字符的两个标记之间的匹配字符串

时间:2019-06-06 00:18:14

标签: regex ruby

我正在尝试编写一个ruby脚本,该脚本将在其他两个字符串之间返回文本。问题是两个匹配的字符串包含特殊字符。转义特殊字符不能解决问题。

我尝试转义特殊字符,不同的匹配模式,并为匹配的字符串提供变量,但运气不佳。

我还通过仅使用 ODS NAME 作为分隔符来测试了简化匹配。那似乎行得通。

####Example contents of logfile 
#### 'aaaaaaaaa ODS | Filename = /tmp/bbbbbb | NAME = ccccc'

log_to_scan = 'logfile'
marker1 = 'ODS | FILENAME = /tmp/'
marker2 = ' | NAME'

contents = File.read(log_to_scan)

print contents.match(/ODS \| FILENAME = \/tmp\/(.*) \| NAME/m[1].strip

print contents.match(/marker1(.*)marker2/m)[1].strip

鉴于上面的示例内容,我希望输出为bbbbbb。但是,我什么也没收到或出现了NoMethod错误。不知道还有什么是真的,或者我做错了什么。

3 个答案:

答案 0 :(得分:3)

str = 'aaaaaaaaa ODS | Filename = /tmp/bbbbbb | NAME = ccccc'
marker1 = 'ODS | FILENAME = /tmp/'
marker2 = ' | NAME'

r = /(?<=#{Regexp.escape(marker1)}).*(?=#{Regexp.escape(marker2)})/i
  #=> /(?<=ODS\ \|\ FILENAME\ =\ \/tmp\/).*(?=\ \|\ NAME)/i 
str[r]
  #=> "bbbbbb" 

r = /#{Regexp.escape(marker1)}(.*)#{Regexp.escape(marker2)}/i
str[r,1]
  #=> "bbbbbb" 

,或者,如果已知要匹配的字符串是小写字母,或者允许将该字符串小写返回:

s = str.downcase
  #=> "aaaaaaaaa ods | filename = /tmp/bbbbbb | name = ccccc" 
m1 = marker1.downcase
  #=> "ods | filename = /tmp/" 
m2 = marker2.downcase
  #=> " | name" 
id1 = s.index(m1) + m1.size
  #=> 32
id2 = s.index(m2, id1+1) - 1
  #=> 37
str[id1..id2]
  #=> "bbbbbb"

请参见Regexp::escape。在#1中,

(?<=#{Regexp.escape(marker1)})

正后方,要求marker1出现在比赛之前。

(?=#{Regexp.escape(marker2)})

正向超前,要求marker2立即关注比赛。

在#3中,我使用了String#index的形式,该形式带有第二个参数(“偏移”)。

答案 1 :(得分:2)

您的原始表达式很好,如果您的字符串输入中可能还有其他空格,并且可以正常工作,我们会在这里稍作修改:

^.+?ODS(\s+)?\|(\s+)?FILENAME(\s+)?=(\s+)?\/tmp\/(.+?)(\s+)?\|(\s+)?NAME(\s+)?=(\s+)?(.+?)$

,我们期望的输出位于这两个捕获组中:

(.+?)

测试

re = /^.+?ODS(\s+)?\|(\s+)?FILENAME(\s+)?=(\s+)?\/tmp\/(.+?)(\s+)?\|(\s+)?NAME(\s+)?=(\s+)?(.+?)$/mi
str = 'aaaaaaaaa ODS | Filename = /tmp/bbbbbb | NAME = ccccc'

# Print the match result
str.scan(re) do |match|
    puts match.to_s
end

Demo

答案 2 :(得分:1)

String#scanf怎么样?

> require 'scanf'
> str = 'ODS | FILENAME = /tmp/ | NAME'
> str.scanf('ODS | FILENAME = %s | NAME')
=> ["/tmp/"]