【问题标题】:How can I use vim regex to replace text when math divide is involved in the expression当表达式中涉及数学除法时,如何使用 vim 正则表达式替换文本
【发布时间】:2015-05-06 09:13:03
【问题描述】:

我正在使用 vim 处理如下文本

0x8000   INDEX1 ....
0x8080   INDEX2 ....
....
0x8800   INDEXn ....

我想使用正则表达式来获取每行的索引号。那是

0x8000 ~ 0
0x8080 ~ 1
....
0x8800 ~ n

数学计算应为 (hex - 0x8000) / 0x80。我正在尝试使用 vim 正则表达式替换来获得行中的结果

%s/^\(\x\+\)/\=printf("%d", submatch(1) - 0x8000)

这将产生

0     INDEX0
128   INDEX1
....
2048  INDEXn

我想要做的是进一步将其更改为

0     INDEX0
1     INDEX1
...
20    INDEXn

也就是说,我想将第一列进一步划分为 0x80。这是我遇到问题的时候。

原始参数是“submatch(1) - 0x8000”。我现在向它添加一个“/0x80”,形成

%s/^\(\x\+\)/\=printf("%d", (submatch(1) - 0x8000)\/0x80)

现在Vim报错

Invalid expression: printf("%d", (submatch(1) - 0x8000)\/0x80))

看起来 vim 在处理“/”时遇到了问题。我也尝试使用单个“/”(没有转义),但仍然失败。

谁能帮我解决这个问题?

【问题讨论】:

    标签: regex vim eval


    【解决方案1】:

    您不能在sub-replace-expression 中使用分隔符。
    :h sub-replace-expression

    注意:分隔符不能出现在表达式中! 考虑使用像“@”或“:”这样的字符。如果结果没有问题 的表达式包含分隔符。

    改为将分隔符更改为不再匹配除法运算符。例如,使用#

    :%s#^\(0x\x\+\)#\=printf("%d", (submatch(1) - 0x8000)/0x80)
    

    请注意,我必须更改您的正则表达式(特别是将 ^\(\x\+\) 更改为 ^\(0x\x\+\))。我不知道为什么你的对你有用,但从:h character-classes\x 不应该包括尾随0x

    /\x     \x      \x      hex digit:                      [0-9A-Fa-f] 
    

    此外,您的正则表达式使用非常神奇的模式更容易阅读(至少对我而言)(请参阅:h magic):

    :%s#\v^(0x\x+)#\=printf("%d", (submatch(1) - 0x8000)/0x80)
    

    【讨论】:

    • 谢谢!这真的有效。您对“0x”是正确的,这是我在线程中的错字,我实际上将它包含在我的实际使用中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 2012-04-27
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    相关资源
    最近更新 更多