Bash 正则表达式匹配前的空格

Bash 正则表达式匹配前的空格

我正在尝试将文本文件中的一行与

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 没有多行模式的概念,^可以在主题的开头匹配,但也可以在每个换行符之后匹配,就像使用perls时一样(?m)。一些 ERE 实现(例如 ast-open 的 ERE 实现)确实支持将其作为扩展([[ a =~ \Aa ]]在 ksh93 中工作),但无论如何,多行模式都不是默认模式,因此您最好^使用\A.

即使在perl,[\A]也不会匹配主题开始[...]旨在匹配一个字符(或有时是整理元素)。[\A]将在 ERE 或Aperl 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  ]]

我删除了[]周围的单个字符。

相关内容