我正在尝试将文本文件中的一行与
if [[ ${regel} =~ ([\s][CN][G]{2}[A]{2}[T]) ]];
我还尝试代替 /s 使用 /A 和 /b 几个我尝试过的例子:
if [[ ${regel} =~ (\A[CN][G]{2}[A]{2}[T]) ]];
if [[ ${regel} =~ (\b[CN][G]{2}[A]{2}[T]) ]];
if [[ ${regel} =~ ([\A][CN][G]{2}[A]{2}[T]) ]];
if [[ ${regel} =~ ([\b][CN][G]{2}[A]{2}[T]) ]];
如果我删除第一个来使所有这些都不匹配
if [[ ${regel} =~ ([CN][G]{2}[A]{2}[T]) ]];
它将匹配我想要匹配的内容,但我希望它与前面的空间匹配,这样它也不需要中线字符串。
我想要的匹配示例:
OZBMN6HH1KI CGGAATGGGGGGGGGGGGGGGCGAGAATCTGAAATAGAGTGGTGACGTGCTGCGTTGACATAGGTCCTAGGGACCACCAG
我究竟做错了什么?我怎样才能使它匹配␣CGGAAT
?
答案1
bash
中的正则表达式[[ =~ regex ]]
是 POSIX 扩展正则表达式。在扩展正则表达式的扩展超出 POSIX 指定范围的系统上(例如支持\s
(尽管不在方括号表达式内)或\b
)的 GNU 正则表达式,您只能在 bash 中将它们用作不带引号的扩展的一部分(除非您打开 bash-3.1 兼容性) :
[[ a =~ \ba ]] # returns false
[[ a =~ $(printf %s '\ba') ]] # returns true on GNU systems
BASH_COMPAT=3.1; [[ a =~ '\ba' ]] # returns true on GNU systems
re='\ba'; [[ a =~ $re ]] # returns true on GNU systems.
如果\A
你的意思是主题开始,那么我们讨论的是 perl 或 perl 兼容的正则表达式,它们又是不同的正则表达式。
标准 ERE 没有多行模式的概念,^
可以在主题的开头匹配,但也可以在每个换行符之后匹配,就像使用perl
s时一样(?m)
。一些 ERE 实现(例如 ast-open 的 ERE 实现)确实支持将其作为扩展([[ a =~ \Aa ]]
在 ksh93 中工作),但无论如何,多行模式都不是默认模式,因此您最好^
使用\A
.
即使在perl
,[\A]
也不会匹配主题开始。[...]
旨在匹配一个字符(或有时是整理元素)。[\A]
将在 ERE 或A
perl RE 中匹配。将匹配 ERE 中的或以及 perl RE 中的退格字符。在 ERE上或中,与perl RE 中的(空白字符)相同。\
A
[\b]
b
\
[\s]
s
\
\s
如果您想使用标准 ERE匹配[CN]G{2}A{2}T
主语开头 ( \A
) 或非单词字符 ( ) 后面的a,您可以这样做:\b
[[ $var =~ (^|[^[:alnum:]_])[CN]G{2}A{2}T ]]
答案2
\A
、\b
和\s
分别是 Perl 的“字符串开头”、“单词边界”和“空白字符”。 (参见perlre
手册页) Bash 使用的扩展正则表达式不支持它们。
在 ERE 中,字符串的开头表示为^
,任何空白字符都可以与 匹配[[:space:]]
,或者如果您只想匹配空格,则可以与文字空格匹配。在某些系统(至少是 GNU)上,您可以用 表示左词边界,\<
用 表示右词边界\>
。在其他情况下,它们可能与文字<
和匹配>
。
但是,使用空格和反斜杠,您会遇到 Bash 如何解析条件中的正则表达式的问题。文字未加引号的空格结束 RE,反斜杠仍然转义字符。为了解决这个问题,首先将正则表达式存储在变量中:
re=' [CN]GGAAT'
if [[ $regel =~ $re ]]; then echo y; fi
或者,如果\<
有效并且您想使用它:
re='\<[CN]GGAAT'
if [[ $regel =~ $re ]]; then echo y; fi
答案3
[\s]
用。。。来代替[[:space:]]
。我不确定它的起源[\s]
是什么,但是其他的也曾有过类似的误解。因此,正确的形式是
>if [[ ${regel} =~ ([[:space]][CN][G]{2}[A]{2}[T]) ]];
答案4
您可以将空格与带引号的空格匹配:
if [[ ${regel} =~ ' '[CN]G{2}A{2}T ]]
我删除了[]
周围的单个字符。