【问题标题】:How to extract path from a string in ruby (between 1st and last fwd slash inclusive)如何从 ruby​​ 中的字符串中提取路径(在第一个和最后一个正斜杠之间)
【发布时间】:2016-07-30 20:56:51
【问题描述】:

我一直在编写一个 ruby​​ 脚本,它遍历一个文本文件并定位所有以输出路径开头的行并将其存储到该行的字符串 (linefromtextfile) 中。所以通常它定位如下行

"output_path":"/data/server/output/1/test_file.txt","text":
"output_path":"/data/server/output/2/test_file.txt","text":

我只想从行中提取路径名 (pathtokeep) 并写入文件,即:

/data/server/output/1/
/data/server/output/2/

我已经尝试过这个正则表达式,但它不起作用:

pathtokeep=linefromtextfile.split(?:\$/.*?/)([^/]*?\.\S*)

请有人在这里就我的 RegEx 提出建议 - 拆分是正确的方法还是有更简单的方法来做到这一点?

【问题讨论】:

  • 你不需要感谢每个答案的作者。如果你这样做了,有一天你会面临选择感谢某人的糟糕答案,或者忽略对那个人的感谢,留下明显的暗示。如果您查看其他问题,您会发现 SO 还没有完成。
  • 以后,当您给出示例时,为每个输入对象分配一个变量会很有帮助。这里可能是str = '"output_path":"...xt":'。这样,读者可以在答案和 cmets 中引用这些变量,而无需定义它们。

标签: ruby regex string pathname


【解决方案1】:

如果您的文件始终具有相同的结构,您也可以不使用正则表达式。

line = '"output_path":"/data/server/output/1/test_file.txt","text":'

path = line.split(/:"|",/)[1]
# => "/data/server/output/1/test_file.txt"

basename = File.basename(path)
# => "test_file.txt"

File.dirname(path) + '/'
# => "/data/server/output/1/"

【讨论】:

  • 我用File.dirname(path)而不是path.gsub(base name, '')改进了它
【解决方案2】:

我建议尽可能使用 Ruby 方法,仅使用正则表达式从字符串中提取路径。

str = '"output_path":"/data/server/output/1/test_file.txt","text":'

r = /
    :"      # match a colon and double quote
    (.+?)   # match one or more of any character, lazily, in capture group 1 
    "       # match a double quote
    /x      # free-spacing regex definition mode

File.dirname(str[r,1])
  #=> "/data/server/output/1"

如果你真的想要尾部正斜杠,

File.dirname(str[r,1]) << "/"
  #=> "/data/server/output/1/"

如果你需要它,

File.basename(str[r,1])
  #=> "test_file.txt"

我将把它留给 OP 来读取和写入文件。

如果你坚持使用单个正则表达式,你可以这样写:

r = /
    (?<=:") # match a colon followed by a double-quote in a positive lookbehind
    .+      # match one more characters, greedily
    \/      # match a forward slash
    /x

str[r]
  #=> "/data/server/output/1/"

请注意,.+ 是贪婪的,它会吞噬所有字符,直到到达字符串中的最后一个正斜杠。

【讨论】:

  • 感谢@guitarman,他的回答提醒我,我不需要在正则表达式中转义引号。
  • 感谢您的提示
【解决方案3】:

试试这个正则表达式:

(?<="output_path":")(.*?)(?=")

Live Demo on Regex101

它是如何工作的:

(?<="output_path":")     # Lookbehind for "output_path":"
(.*?)                    # Data inside "" (Lazy)
(?=")                    # Lookahead for closing "

【讨论】:

  • 感谢您的反馈。也用于 Regex101 的链接 - 方便!
  • @adamjth 如果这些答案之一回答了您的问题,请将其标记为已接受(按投票按钮下方的勾号)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-06
  • 1970-01-01
  • 2016-07-10
  • 1970-01-01
相关资源
最近更新 更多