2

这是我的参数:

  • 我需要将 MM/DD/YYYY(MM-DD-YYYY、MM.DD.YYYY 等)更改为 MONTH、DAY YEAR。例如:2001 年 1 月 29 日 => 2001 年 1 月 29 日。
  • 这是为了人类阅读的输出。我需要在多台计算机上多次进行此更改。以前负责此任务的人一直是手工完成的。
  • 我可以依赖 VIM(因为它在拇指驱动器上),但当我使用它时,计算机上没有其他东西。

挑战:在每台计算机上制作一个正则表达式来快速解决这个问题。

这就是我所拥有的(使用#'s 作为分隔符):

%s#\([1-9]\|1[012]\)[- /.]\([1-9]\|[12][0-9]\|3[01]\)[- /.]\([19\|20]\d\d\)#UGLYPART \2, \3#g

搜索部分正常工作,因为我在正确的位置得到了 \2 和 \3。我知道 UGLYPART 将使用 \1,然后进行某种评估,例如:

((\1)\=(1\|2\|3\|4\|5\|6\|7\|8\|9\|10\|11\|12)(January\|February\|March\|April\|May\|June\|July\|August\|September\|October\|November\|December)) 

除了它会起作用。

有没有人有任何见解?我觉得我大约有 90% 在那里。还是我对 Vim 的正则表达式要求太多了?

4

2 回答 2

4

是的,您应该使用\=,但它以另一种方式使用:

%s#\v([1-9]|1[012])[\- /.]([1-9]|[12][0-9]|3[01])[- /.]((19|20)\d\d)#\=strftime('%B', 28*24*60*60*submatch(1)).' '.submatch(2).', '.submatch(3)#g

注意:[]是一个集合,因此[19\|20]您在此处编写的内容被视为1, 9, \, |,20. 你应该使用\(19\|20\). 并用于\v避免不必要的逃逸。

注2:我不想写月份列表。您可以看到一年中的第 28 天是 1 月,28*2=56 是 2 月,28*3=84 是 3 月等等直到 12 月,所以您可以使用函数和时间戳(以秒为单位)是 1 月 1 日strftime()这一事实0(不是当年的,但这没关系)。不过这取决于语言环境:在英语语言环境中strftime('%B', 28*24*60*60*1)会输出“January”,但在我的系统上会输出“Январь”。

注意 3:\=必须始终位于替换字符串的第一个位置。

于 2012-04-11T16:07:02.687 回答
1

我认为您可以使用 -e 在“行编辑”(ex)模式下使用 vim。然后给它一个编辑命令文件

假设这些命令在 date.ex 中:

g/\([0-9][0-9]*\)[./-]1[./-]\([012][0-9][0-9]*\)/s//January \1, \2/
g/\([0-9][0-9]*\)[./-]2[./-]\([012][0-9][0-9]*\)/s//February \1, \2/
g/\([0-9][0-9]*\)[./-]3[./-]\([012][0-9][0-9]*\)/s//March \1, \2/
... etc ...
w
q

然后调用 vim 作为

vim -e -S date.ex foo

其中 foo 是您要编辑的文件。所以 yoy 可以有一个 shell 脚本来跨文件系统中的所有文件运行它。

于 2012-04-11T15:33:38.130 回答