如何使用sed分割含有连字符的单词?

时间:2017-02-16 10:28:42

标签: regex sed

我想使用<android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="@color/colorAccent" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:expandedTitleTextAppearance="@style/CustomCollapsingExpanded" app:collapsedTitleTextAppearance="@style/CustomCollapsingCollapsed" > 拆分带有连字符的单词。不在单词内的连字符应保持原样。例如,对于句子:

sed

我想要输出:

"the multi-modal solution is an award-winning approach in the 21st-century - however"

我尝试使用:

"the multi @-@ modal solution is an award @-@ winning approach in the 21st @-@ century - however"

没有成功。我正在使用sed的OSX版本。

4 个答案:

答案 0 :(得分:2)

您可以使用awk

来使用此非正则表达式实现
s="the multi-modal solution is an award-winning approach in the 21st-century"
awk -F '-' -v OFS=' @-@ ' '{$1=$1} 1' <<< "$s"

the multi @-@ modal solution is an award @-@ winning approach in the 21st @-@ century

参考: Effective AWK Programming

Sed解决方案(适用于OSX):

sed -E 's/([^-[:blank:]]+)-([^-[:blank:]]+)/\1 @-@ \2/g' <<< "$s"

答案 1 :(得分:2)

使用您自己的解决方案尝试的固定版本来补充anubhava's answer中的sed -E解决方案:

sed 's/\([a-zA-Z0-9]\{1,\}\)-\([a-zA-Z0-9]\{1,\}\)/\1 @-@ \2/g' test.txt > test2.txt

也就是说,ERE (extended regex)量词结构+必须使用BRE (basic regex)中的\{1,\}进行模拟,sed默认使用{。}}。

可选背景信息

正如Sundeep在对该问题的评论中指出的那样, GNU sed允许使用\+(当不使用-r-E,支持ERE),但这是macOS sed版本不支持的非标准扩展。

sed POSIX spec 支持 BRE ,特别是POSIX BREs

因此,要编写便携式 sed命令:

  • 既不使用-r(GNU sed更新版本的BSD sed)也不使用-E(GNU和BSD / macOS sed

  • 仅使用POSIX BRE features,避免特定于实施的扩展,特别是:

    • 使用\{1,\}代替\+(相当于ERE +)。
    • 使用\{0,1\}代替\?(相当于ERE ?)。
    • 避免使用GNU \|进行更改:遗憾的是,POSIX BRE根本不支持轮换。

利用更强大的现代语法ERE,同时支持 GNU BSD sed(包括macOS)的平台:

要了解给定sed实现的特定(非标准)正则表达式功能:

  • GNU Sed(Linux):

    • info sed,自GNU Sed 4.2.2起,解释

      • GNU BRE 章节&#34; 3.3正则表达式语法概述&#34;

        • BRE扩展名为\+\?\|; a**被视为与a*相同(不必逃避第二个*)仅适用于 EREs
      • GNU ERE 语法&#34;附录A扩展正则表达式&#34;。

        • 但是,只讨论了与BRE的对比,以及许多ERE扩展 - 其中包括\d\s等字符类快捷方式,\<等字边界断言/ \>\b,除了\n之外的控制字符转义序列(例如\t)和基于代码点的转义序列(例如\x27)<那里没有提到。
    • (相比之下,man re_format / man 7 regex仅包含POSIX信息。)

  • BSD / macOS Sed:

    • man re_format确实适用(讨论BRE和ERE),但增强功能部分除外,这些部分不受支持。
    • 提到的唯一扩展是字边界断言[[:<:]][[:>:]]

有关GNU Sed和BSD Sed之间所有差异的全面概述,请参阅我的this answer

答案 2 :(得分:1)

这可能适合你(GNU sed):

sed 's/\>-\</ @-@ /g' file

用所需的字符串替换字边界的结尾/开头所包围的超量。

答案 3 :(得分:0)

  s="the multi-modal solution is an award-winning approach in the 21st-century - however"
awk -F century '{gsub(/-/," @&@ ",$1)}1'  <<< "$s" OFS=century

the multi @-@ modal solution is an award @-@ winning approach in the 21st @-@ century - however