在 GNU sed 中它可以工作。例如,这匹配多行模式空间中的两个空行(使用 创建N
)
/^\n$/
这是标准吗?
答案1
是的。
句点在括号表达式
.
之外使用时为 [n] [BE]RE,它将匹配支持的字符集中除 NUL 之外的任意字符。[
]
许多 POSIX 正则表达式实现(例如grep
或sed
)匹配换行符并不困难,因为.
不会匹配它,而是因为它们的输入分隔符是换行符 - 所以它们在扫描的字符串中没有任何换行符要匹配。
POSIXgrep
永远无法匹配换行符 - 它与空字符串同义grep
。sed
类似,除了 ased
可以根据脚本命令执行编辑或拉入额外输入,并且这些结果可能包括模式空间中的换行符,即使它们永远不会在那里发生。但在这种情况下,.
将会与 ewline 匹配\n
。
据我所知,几乎任何 POSIX 实现都无法完成一件事,那就是匹配^
换行符的补码。这是因为\
反斜杠代表[
括号表达式中的自身]
,因此\n
那里的转义仅意味着\
and n
。因为在正则表达式中包含文字换行符通常也是语法错误(尽管pax
这是我知道的一个例外),你不能这样做[^
<newline>
]
便携式。
健全的实现应该处理"[$(printf '\1-\11\13-\377')]"
,但这限制了多字节场景中的匹配。
还有:"\(\([^[:space:]]*[[:blank:]$(printf '\r\v\f')]*\)*\)"
但这有点笨拙。
不过,您可以做的就是暂时将模式空间中的所有换行符与其他字符交换(当然,反之亦然),然后匹配该其他字符的补集。
例如:
printf %s\\n "a a" "b b" "c c" |
sed -e 'H;1h;$!d;x;l' -e '# slurps input to last line - usually a bad idea' \
-e 'y/ \n/\n /;l' -e '# transliterates spaces and newlines at once' \
-e 's/[^ ]*//2;l' -e '# substitutes away 2cd sequence of not spaces' \
-e 'y/ \n/\n /;l' -e '# transliterates spaces and newlines again'
a a\nb b\nc c$
a\na b\nb c\nc$
a\na c\nc$
a a\n\nc c$
a a
c c
那个小脚本中有 4 个l
ook 命令 - 一个用于在找到最后一行后每次更改模式空间。每个l
ook 命令对应于上面的前四个输出行之一,这些输出行很容易用尾随$
字符标记。
最后三行是sed
默认打印到 stdout 的所有编辑的结果。第二行完全是空的,因为sed
替换了空格字符的补码的第二个序列,它匹配当时模式空间中除输入换行符之外的所有字符,因此第二个序列是整个第二行,减去其尾随换行符分隔符。
重要的是,这有效因为点(或其更具限制性的[
括号表达式]
替代方案)匹配换行符。