如何在统一差异中正确解析范围信息?

时间:2017-03-02 03:14:42

标签: ruby git diff

基本上,我想要做的是查看统一差异的范围信息,并确切地知道我应该注意哪些代码行。

例如,这个:

@@ -1827,7 +1827,7 @@

这告诉我总共只有1行发生了变化,因为差异在变化的上方和下方显示3行(所以7 - 6 = 1),它也指向了1830行(即1827 + 3)

为了更迂腐,这个特定的范围信息实际告诉我,在第1830行,删除了一行( - ),并在第1830行添加了一行(+)。

或者更明显地考虑另一个差异的范围信息:

@@ -878,15 +878,13 @@

这告诉我的是,在第881行(878 + 3),删除了9行(15 - 6),但在第881行只添加了7行(13 - 6)。

所以问题是,使用正则表达式或其他一些Ruby字符串方法,我如何轻松地提取上述信息?

即。如何轻松提取此信息:

  • 两者行号(即只是1827或878),我可以加上+3来确定我关心的实际内联号码。 必须两者都是因为两条线可能并不总是相同。
  • 受影响的行数(在上述示例中7后面的1513,
  • 当我这样做时,我如何确保跟踪每个操作的操作(添加或删除)。

我尝试切割字符串并直接转到字符 - 例如myString[3]给了我-,但这是唯一可靠的字符,因为行号可以是1,10,100,1000,10000等。所以唯一的方法是只扫描字符串,然后解析它。

修改1

添加一些代码以显示我尝试过的内容。

假设我在名为@diff_lines的变量中有diff的内容:

@diff_lines.each do |diff_line|
  if diff_line.start_with?("@@")
    del_line_num_start = diff_line.split(/@@ /).second.split.first.split(/-/).second.split(/,/).first.to_i + 3
    num_deleted_lines = diff_line.split(/@@ /).second.split.first.split(/-/).second.split(/,/).second.to_i - 6
    add_line_num_start = diff_line.split(/@@ /).second.split.second.split(/\+/).second.split(/,/).first.to_i + 3
    num_added_lines = diff_line.split(/@@ /).second.split.second.split(/\+/).second.split(/,/).second.to_i - 6

正如你所看到的,上面的作品......但看起来非常可怕,而且显然不是很干。

理想情况下,我希望能够实现同样的目标,但只是更清洁。

1 个答案:

答案 0 :(得分:2)

一般的想法是编写一个包含捕获组的正则表达式((...)),将该字符串拆分为有用的东西。例如:

diff_line.match(/\A@@\s+\-(\d+),(\d+)\s+\+(\d+),(\d+)\s+@@/)

这会在成功匹配时产生MatchData个对象。然后,您可以将其应用于某些变量,例如:

if (m = diff_line.match(...))
  a_start, a_len, b_start, b_len = m[1..4].map(&:to_i)
end

然后你可以对这些数字进行任何计算。

如果您在查看正则表达式的功能时遇到问题,请尝试使用Rubular之类的工具来更好地说明内部结构。