【问题标题】:Removing non-alphanumeric characters with sed使用 sed 删除非字母数字字符
【发布时间】:2013-11-29 05:06:17
【问题描述】:

我正在尝试验证一些输入以删除一组字符。只允许使用字母数字字符加号、句点、下划线、连字符。我已经测试了正则表达式 [^\w.-] 这里 http://gskinner.com/RegExr/ 并且它与我想要删除的内容相匹配,所以我不确定为什么 sed 会返回相反的结果。我错过了什么?

我的最终目标是输入"Â10.41.89.50 " 并得到"10.41.89.50"。

我试过了:

echo "Â10.41.89.50 " | sed s/[^\w.-]//g 返回Â...

echo "Â10.41.89.50 " | sed s/[\w.-]//gecho "Â10.41.89.50 " | sed s/[\w^.-]//g 返回 Â10418950

我尝试在Skip/remove non-ascii character with sed 找到答案,但没有删除任何内容。

【问题讨论】:

  • 尝试将-r 选项添加到sed,以便它能够识别扩展的正则表达式。
  • sed 不理解像 \w 这样的特殊字符类。只需使用[a-zA-Z0-9_-]
  • -r 和使用[a-zA-Z0-9_-] 都不起作用。好吧,echo "Â10.41.89.50 " | sed s/[a-zA-Z0-9.-]//g 返回了Â,但echo "Â10.41.89.50 " | sed s/[^a-zA-Z0-9.-]//g 仍然返回了Â10.41.89.50

标签: regex bash sed replace


【解决方案1】:

好吧 sed 不支持 unicode 字符。请改用perl

> s="Â10.41.89.50 "
> perl -pe 's/[^\w.-]+//g' <<< "$s"
10.41.89.50

【讨论】:

  • @jthill:我的 OSX 上没有(可能是由于某些语言环境)。
  • 所以看起来我的 OSX 10.6.8 上的 sed 不支持 unicode,但 gnu-sed 应该支持 unicode。
  • @gorideyourbike:很公平,请随意使用任何其他答案。
  • @anubhava 不应该是语言环境,perl 尊重这一点。我想苹果有一个后级 sed,sed --version 说什么?
  • @jthill: sed --version 给出错误:sed: illegal option -- -
【解决方案2】:

您可能想改用[:alpha:] 类:

echo "Â10.41.89.50 " | sed "s/[[:alpha:].-]//g"

应该可以。如果没有,您可能需要更改本地设置。

另一方面,如果您只想保留数字、连字符和句点::

echo "Â10.41.89.50 " | sed "s/[^[:digit:].-]//g"

如果您的字符串在变量中,则可以使用纯 bash 和 parameter expansions

$ dirty="Â10.41.89.50 "
$ clean=${dirty//[^[:digit:].-]/}
$ echo "$clean"
10.41.89.50

$ dirty="Â10.41.89.50 "
$ clean=${dirty//[[:alpha:]]/}
$ echo "$clean"
10.41.89.50

你也可以看看1_CR的回答。

【讨论】:

  • @dw1:不,我不这么认为。在第一个示例中,我们想要删除所有字母、句点和连字符,这就是命令的作用(sed 将这些符号替换为任何内容)。最后一个例子是相同的逻辑,但是有 Bash 的参数扩展。
【解决方案3】:

-c(补码)标志可能是一个选项

echo "Â10.41.89.50-._ " | tr -cd '[:alnum:]._-'

【讨论】:

  • @AlexanderMills, @Herlon, 虽然上面的 tr 咒语符合 POSIX,但我没有方便测试的 MacOS
  • 这个答案在 macOS 上运行良好,只是语言环境在 :alnum: 字符类中包含非英文字母(应该如此)。如果你想删除非英文字符,试试这个:echo "Â10.41.89.50-._ /" | tr -cd '[a-zA-Z0-9]._-'
  • @iruvar,我认为你需要删除那些额外的括号(类是 '[:alnum:]' 而不是 '[[:alnum:]]' 并且 tr 不是 sed/perl 等.) 否则您的表达式将允许那些非字母数字('[', ']')通过。我刚刚打了这个
【解决方案4】:
<`[[:alnum:]_.@]`

这对我来说效果很好。它保留了我为我的目的指定的所有字符。

【讨论】:

    【解决方案5】:
    s/[^[:alnum:]+._-]//g
    

    删除字母数字和“.+_-”字符以外的任何字符。

    echo "Â10.41.89.50 +-_" | sed s/[^[:alnum:]+._-]//g
    Â10.41.89.50+-_
    

    【讨论】:

    • 请提供一些解释
    • @user3142695 这不是手册的替代品。这从那里回答了 Q. man sed。没有技巧。没有恶作剧。那里没有火箭科学。
    • 不,这会将输入的第一个字符替换为空 - ^ 是 sed 中字符串的开头
    【解决方案6】:

    要删除除字母数字和“-”之外的所有字符,请使用以下代码:

    echo "a b-1_2" | sed "s/[^[:alnum:]-]//g"
    

    【讨论】:

      猜你喜欢
      • 2015-03-24
      • 1970-01-01
      • 2012-07-04
      • 2015-04-08
      • 1970-01-01
      • 1970-01-01
      • 2014-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多