【问题标题】:Perl: Why can't divide?Perl:为什么不能除法?
【发布时间】:2019-02-12 09:30:07
【问题描述】:

为什么除法不起作用?

echo 'cb0' | perl -p -e 's/(\w{3})/sprintf("%d", ( hex($1)/4 ))/e'

Number found where operator expected at -e line 1, near
"s/(\w{3})/sprintf("%d", ( hex($1)/4" syntax error at -e line 1, near
"s/(\w{3})/sprintf("%d", ( hex($1)/4" Execution of -e aborted due to
compilation errors.

原始输入数据是 12 位十六进制数。

【问题讨论】:

  • 除法中的/ 被视为正则表达式的分隔符。为什么要在替换零件中进行划分?你的输入数据是什么?很可能,unpack 是一个更好的选择。

标签: perl divide


【解决方案1】:

替换 s/// 的默认分隔符不平衡,因此您会收到错误消息。这是因为您将 $1 除以 4 并引入了另一个 '/' 。因此,为了安全起见,请使用其他字符,而不是会弄乱表达式的字符。在这种情况下,最好使用 作为分隔符

$ echo 'cb0' | perl -p -e 's<(\w{3})><sprintf("%d", ( hex($1)/4 ))>e '
812

当您将 s/// 与其他分隔符转换时,您必须配对 <...>、(...)、[...] 和 {...}。我选择了 因为它不在表达式中。

【讨论】:

  • 您没有解释为什么您认为&lt;...&gt;|...| 更好。你应该解释为什么/.../.../ 变成&lt;...&gt;&lt;...&gt; - 中间有两个分隔符。
  • Re "我选择&lt;&gt;,因为它没有表达式。",&lt;&gt;最好的部分是&lt;和@ 987654330@ 是表达式的一部分,只要它们是成对的。 {} 更有可能发生这种情况,因此通常是更好的选择。
  • 我倾向于使用#(哈希或磅),因此's#(\w{3})#sprintf("%d", ( hex($1)/4 ))#e' formats work fine for me (though it did confuse the gvim syntax highlighter, that thought the #`是一个评论:))
  • # -- 用于 cmets 和 "|"用于管道到其他命令..所以在这种情况下我的最佳做法是使用
  • @stack0114106:详细信息are here
【解决方案2】:

这不起作用:

$ echo 'cb0' | perl -p -e 's/(\w{3})/sprintf("%d", ( hex($1)/4 ))/e'
Unknown regexp modifier "/4" at -e line 1, at end of line
syntax error at -e line 1, near "s/(\w{3})/sprintf("%d", ( hex($1)/4 )"
Execution of -e aborted due to compilation errors.

这样做:

$ echo 'cb0' | perl -p -e 's/(\w{3})/sprintf("%d", ( hex($1)\/4 ))/e'
812

这样做,可能更容易理解:

$ echo 'cb0' | perl -p -e 's|(\w{3})|sprintf("%d", ( hex($1)/4 ))|e'
812

当您在替换中使用/ 字符作为分隔符时,表达式中出现的所有/ 都将被视为分隔符。如果您希望将其视为其他东西(例如除法运算符),则需要对其进行转义(通过将\ 放在它前面)。

另一种选择是为您的替换选择不同的分隔符。在我的第三个示例中,我改用|。在这种情况下,/ 不再被视为特殊且不需要转义。

【讨论】:

    【解决方案3】:

    要么使用不同的分隔符进行替换,要么您需要使用反斜杠转义分隔符:

    echo 'cb0' | perl -p -e 's/(\w{3})/sprintf("%d", ( hex($1)\/4 ))/e'
    

    【讨论】:

      猜你喜欢
      • 2011-03-23
      • 1970-01-01
      • 1970-01-01
      • 2010-12-26
      • 2010-10-17
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 2010-09-27
      相关资源
      最近更新 更多