【发布时间】:2011-11-23 03:46:38
【问题描述】:
sed 中的某个字符“不是”怎么说?
【问题讨论】:
-
[^X]是除X之外的任何字符。 PS 虽然我们知道你的意思,但 SED 不应该大写 -
@Sanjay 好的,我将取消大写 sed。下次能不能在回答区发个答案,不是cmets?
sed 中的某个字符“不是”怎么说?
【问题讨论】:
[^X] 是除X 之外的任何字符。 PS 虽然我们知道你的意思,但 SED 不应该大写
[^x]
这是一个接受除x之外的任何字符的字符类。
【讨论】:
su[^x]\? 将匹配“sux”,因为子字符串“su”满足正则表达式。您将 x 从匹配中排除,而不是阻止带有 x 的内容匹配。 (如果条件之后有某些内容,这可能会起作用,例如su[^x]\?$)
\(su[^x]\|su$\)(我认为更短的形式 su\([^x]\|$\) 也可以工作)。
根据我自己的经验,下面的帖子支持这一点,sed 不支持使用“^”的正常正则表达式否定。我不认为 sed 有直接否定的方法......但如果你查看下面的帖子,你会看到一些解决方法。 Sed regex and substring negation
【讨论】:
sed 支持 [^...] 否定就好了。不过,也许您对这个结构的理解并不完整?不过,链接的问题很有用。
[^http] 会查找不是(换行符或)h、t 或 p 的单个字符。 (第二个 t 完全是多余的,但正则表达式引擎可以容忍。)
对于那些对所选答案不满意,根据johnny's comment。
'su[^x]' 将匹配 'sum' 和 'sun' 但不匹配 'su'。
您可以使用以下语法告诉 sed 到 not 匹配行与 x:
sed '/x/! s/su//' file
【讨论】:
x su,即使它应该匹配。你可以做/sux/!s/su//,但这仍然会跳过su sux,可能是第一个,但不是第二个,su 应该匹配。理想情况下,OP 应该明确要求。
\(su[^x]\|su$\)(我认为更短的形式su\([^x]\|$\) 也可以工作)。
您的问题有两种可能的解释。就像其他人已经指出的那样,[^x] 匹配不是x 的单个字符。但是空字符串也不是x,所以也许你正在寻找[^x]\|^$。
这些答案都没有扩展到多字符序列,这通常是人们正在寻找的。你可以煞费苦心地构建类似的东西
[^s]\|s\($\|[^t]\|t\($\|[^r]\)\)\)
编写一个不匹配str 的正则表达式,但sed 中更直接的解决方案是删除任何匹配 匹配str 的行,然后保留其余行;
sed '/str/d' file
Perl 5 引入了一个更丰富的正则表达式引擎,因此它是 Java、PHP、Python 等的标准引擎。因为 Perl 有助于支持 sed 语法的子集,您可以将一个简单的 sed 脚本转换为 Perl从这个扩展的正则表达式方言中使用一个有用的特性,例如否定断言:
perl -pe 's/(?:(?!str).)+/not/' file
将用not 替换不是str 的字符串。 (?:...) 是非捕获组(与许多sed 方言不同,非转义括号是Perl 中的元字符),(?!str) 是否定断言;为了使正则表达式匹配,字符串中此位置之后的文本不得为 str。 + 重复此模式,直到匹配失败。请注意断言如何在匹配中的每个位置都为真,所以我们一次匹配一个字符与.(新手经常会犯这个错误,并且错误地只在例如较长模式的开头进行断言,但是这可能在某处匹配str,导致“泄漏”)。
【讨论】:
sed 示例行之后,我还将包含一个“或对 匹配的每一行进行操作not match" 与一个简单的sed 示例说明如何做到这一点。 (就像我认为可行的sed '/str/! { ... },但如果我错了,那么总是有:、b 和t 来构建任意条件分支。)
除了所有提供的答案之外,您还可以在 sed 中使用符号 [^:[C_CLASS]:] 否定字符类,例如,[^[:blank:]] 将匹配不被视为空格字符的任何内容。
【讨论】: