正则表达式多次匹配git log中的任何内容

时间:2019-04-30 09:47:19

标签: javascript regex

我想将git日志消息分成几部分,以便我可以访问每个提交及其散列和消息。

这是git log命令:

git log --pretty=short --abbrev-commit -n 2 HEAD

以下是示例日志:

commit bfb9bac
Author: XXXXX XXXXXXXX <xxx.xxxxx@xxxxx.xxx>

    Something awesome happened here

commit a4fad44
Author: XXXXX XXXXXXXX <xxx.xxxxx@xxxxx.xxx>

    Ooh, more awesomeness
    So many lines

到目前为止我已经尝试过的:

([a-f0-9]{7})\n(?:Author.+\n\n)([\s\S]+)(?=\ncommit)

此处是RegExr的链接:https://regexr.com/4d523

最后应该看起来像这样:

const result = commits.match(regex)

result[0][0] // bfb9bac
result[0][1] // Something awesome happened here

result[1][0] // a4fad44
result[1][1] // Ooh, more awesomeness\n    So many lines

分两个步骤进行也是可以的;首先拆分提交,然后拆分哈希和消息。

2 个答案:

答案 0 :(得分:2)

您可以通过使用[\s\S]匹配整个字符串,并重复与换行符匹配的模式并断言该字符串不是以commit开头的方式来省略.*的使用:

^commit ([a-f0-9]{7})\nAuthor.*\n+[ \t]+(.*(?:\n(?!commit).*)*)

说明

  • ^字符串的开头
  • commit匹配 commit 后跟一个空格
  • ([a-f0-9]{7})在组1中捕获,匹配字符类中列出的内容的7倍
  • \nAuthor.*匹配换行符,然后对Author和除换行符以外的任何字符进行0倍以上的匹配
  • \n+[ \t]+匹配1次以上换行符,再匹配1个以上空格或制表符
  • (捕获组
    • .*匹配除换行符外的任意字符0+次
    • (?:\n(?!commit).*)*重复与换行符匹配的0+次,断言右边的内容未提交,然后匹配除换行符之外的所有char 0+次
  • )关闭捕获组

Regex demo

const regex = /^commit ([a-f0-9]{7})\nAuthor.*\n+[ \t]+(.*(?:\n(?!commit).*)*)/gm;
const str = `commit bfb9bac
Author: XXXXX XXXXXXXX <xxx.xxxxx@xxxxx.xxx>

    Something awesome happened here

commit a4fad44
Author: XXXXX XXXXXXXX <xxx.xxxxx@xxxxx.xxx>

    Ooh, more awesomeness
    So many lines
`;
let m;

while ((m = regex.exec(str)) !== null) {
  if (m.index === regex.lastIndex) {
    regex.lastIndex++;
  }
  console.log("hash: " + m[1]);
  console.log("message: " + m[2]);
}

答案 1 :(得分:1)

您可以使用此正则表达式来匹配每个提交日志,并捕获group1中的sha1和group2中的消息,

^commit\s+(\S+)\n^Author:[\w\W]+?^\s+((?:(?!commit)[\w\W])+)

正则表达式说明

  • ^commit-在行首开始匹配commit
  • \s+(\S+)\n-匹配一个或多个空格,后跟sha1值,该值使用(\S+)在group1中捕获,后跟换行符\n
  • ^Author:[\w\W]+?-再次从行首开始匹配Author,后跟冒号,再跟任何字符尽可能少地匹配一次或多次
  • ^\s+-从行首开始匹配一个或多个空格,这是消息将从下一个正则表达式部分开始捕获的点
  • ((?:(?!commit)[\w\W])+)-此表达式(aka tempered greedy token )使用[\w\W]捕获包括换行符在内的任何字符,但是如果看到commit并放置则停止捕获组2的整个比赛

Regex Demo

这是一个JS代码演示

str = `commit bfb9bac
Author: XXXXX XXXXXXXX <xxx.xxxxx@xxxxx.xxx>

    Something awesome happened here

commit a4fad44
Author: XXXXX XXXXXXXX <xxx.xxxxx@xxxxx.xxx>

    Ooh, more awesomeness
    So many lines`;

reg = new RegExp(/^commit\s+(\S+)\n^Author:[\w\W]+?^\s+((?:(?!commit)[\w\W])+)/mg);
while(null != (m=reg.exec(str))) {
   console.log("SHA1: " + m[1] + ", Message: " + m[2]);
}