意外的拆分行为

史蒂文·彭尼(Steven Penny)

我在这里阅读有关Awk拆分行为的信息:

拆分函数fs参数(请参见字符串函数)应解释为扩展的正则表达式。这些可以是ERE令牌,也可以是任意表达式,并且应以与or运算符右侧相同的方式进行解释~!~

和:

如果右侧操作数是除词法标记ERE之外的任何表达式,则该表达式的字符串值应解释为扩展的正则表达式,包括上述转义约定。

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html#tag_20_06_13_04

但是,我注意到使用此代码出现了意外的结果:

BEGIN {
  print split("te.st", q, ".")
}

我希望.代表任何字符,结果是6但是我所有的测试都回来了2运行此代码可以得到预期的结果6

BEGIN {
  print split("te.st", q, /./)
}

经过测试:

  • 高克
  • gawk --posix
  • 花胶1.3.4
  • mawk 1.3.3
  • nawk(原始awk)

我是否误解了文档,或者这是一个错误?

满天星

这不是错误;只是在尝试整理现有做法时,该标准还不够清楚。

mawk(1)手册更为明确:

split(expr, A, sep) 的工作方式如下:

...

(2)如sep = " "(一个空格),然后<SPACE>从前面修剪和背部的expr,并sep成为<SPACE>mawk定义<SPACE>为正则表达式/[ \t\n]+/否则sep,将其视为正则表达式,但对于长度为1的字符串,例如,元字符将被忽略split(x, A, "*")并且split(x, A, /*/)它们相同。

另外,来自当前资源的GNU awk手册

split(s, a [, r [, seps] ])

...

拆分的行为与上述字段拆分相同。特别是,如果r是单字符字符串,则即使该字符串恰好是正则表达式元字符,该字符串也将充当分隔符。

这是来自susv4标准的描述

通过将包含表达式的字符串直接分配给内置变量FS或使用该-F sepstring选项的结果,可以使用扩展的正则表达式来分隔字段FS变量的默认值应为单个<space>。下面介绍FS行为:

  1. 如果FS为空字符串,则行为未指定。
  2. 如果FS单个字符

    一种。如果FS为<空格>,则跳过前导和尾随的<空白>和<换行符>;字段应由一组一个或多个<blank>或<newline>字符定界。

    b。否则,如果FS是任何其他字符c,则字段应由每次出现c来界定

  3. 否则,FS的字符串值应被视为扩展的正则表达式。匹配扩展正则表达式的序列的每次出现都应定界字段。

您的示例匹配2.b。

即使有明确提及FSsplit在所有awk实现中(包括在该参数是空格的情况下),使用任何参数代替第3个参数都是相同的行为

这是不太可能的行为永远不会改变,因为FS变量只是一个字符串(awk没有正则表达式对象,如javascriptperl,你不能一个正则表达式分配给一个变量,如a=/./$a=qr/./); 它是split函数(隐式或显式调用),它确实如上所述解释了其参数。

此行为的起源可能与“旧” awk兼容,其中FS(或的第3个参数split)始终被视为单个字符。示例(在Unix v7上):

$ awk 'BEGIN{FS="."; print split("foo.bar.baz", a, "bar"); print a[2] }'
3
ar.
$ awk 'BEGIN{FS="."; print split("foo.bar.baz", a, /bar/); print a[2] }'
awk: syntax error near line 1
awk: illegal statement near line 1
Bus error - core dumped

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章