【问题标题】:Regex: How to get rid of trailing newline symbol in the match?正则表达式:如何摆脱匹配中的尾随换行符?
【发布时间】:2022-01-06 21:54:20
【问题描述】:

我正在寻找一个正则表达式,该表达式将匹配第一个日期,该日期后面不是带有“R”字母的行(我想从git log 获取最后提交日期,除了 仅用于路径更改提交)。

2021-12-07T16:39:43+01:00
M       test.md

2021-12-07T16:18:59+01:00
R100    old.test.md  test.md

2021-12-07T15:37:15+01:00
A       old.test.md

经过一番努力,我得到了这个正则表达式(我不太关心日期的有效性,我相信 Git):

/20[\d-T:.Z+]+(?:\r?\n)(?!R)/

它工作得很好——但它会留下一个尾随换行符\n。没什么大不了的,它可以被替换;但是安全地将matchreplace 链接起来会使代码非常难看(我使用的是Node.js):

import { execSync } from "child_process"

const allAuthorDates = execSync(
  `git log --follow --name-status --pretty=format:%aI -- test.md`
).toString()

const lastEditExceptPathChangeDateMatch = allAuthorDates.match(
  /20[\d-T:.Z+]+(?:\r?\n)(?!R)/
)

console.log(lastEditExceptPathChangeDateMatch)

/*
[
  '2021-12-07T16:39:43+01:00\n', <-- how to get rid of that \n?
  index: 0,
  input: '2021-12-07T16:39:43+01:00\nA\ttest.md\n',
  groups: undefined
]
*/

由于尾​​随换行符,我不得不使用可怕的let result = (str.match(/…/) || [""])[0].replace(…) 来防止运行时错误(可能不太可能)匹配将返回null

有人会这么好心地建议我如何编辑正则表达式以在匹配时摆脱尾随的\n,从而使以下replace变得不必要?

【问题讨论】:

  • 将其移至前瞻,/20[\d-T:.Z+]+$(?!\r?\nR)/m,甚至/^20\d{2}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$(?!\r?\nR)/gm
  • 这不是一个真正的 Git 问题,除非您正在寻找某种方法让 Git 不在那里生成换行符(不幸的是没有一个)。我要剪断git 标签。正则表达式中的换行符往往依赖于正则表达式引擎,特别是它是否允许匹配多个行,包括换行符;我不知道这里的js。当然,第三种方法是在进行正则表达式匹配之前进行一些后处理以完全删除换行符。 :-)
  • @Wiktor Stribiżew 谢谢,它就像一个魅力。 $ 符号与此处的行尾匹配?
  • @torek 很公平,与 Git 无关。谢谢你的解释。

标签: javascript node.js regex


【解决方案1】:

您需要将行尾与$ 匹配(确保添加m 标志),然后使用负前瞻,将\r?\n 模式移动到R 之前的前瞻中:

/20[\d-T:.Z+]+$(?!\r?\nR)/m

this regex demo。或者,如果你想拼出模式:

/^20\d{2}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$(?!\r?\nR)/gm

在这里,我还添加了g 标志来匹配多次出现。见this regex demo

$(?!\r?\nR) 部分匹配 CR 或 LF 字符(回车或换行)之前的位置,然后确保当前位置右侧没有可选的 CR 字符、LF 字符和 R

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 2012-02-27
    • 2012-01-14
    • 1970-01-01
    • 2014-06-30
    相关资源
    最近更新 更多