前言#
在学习正则表达式的时候,在 shell 里面用 egrep 来验证正则表达式,egrep 的基本语法是 egrep [regular expression] [file path],结果会返回目标文件中能匹配到正则表达式的对应行,由于正则表达式中一些元字符在 shell 中也是有特殊意义的,所以为了能正确匹配,需要用单引号 ' 把正则表达式包含起来,但是如果正则表达式里面包含单引号呢,带着这个问题去查了一下,了解了一下shell中的不同的转义方式。
我的
shell用的是Mac上的bash。
bash 中的三种不同转义方式#
| 字符 | 说明 |
|---|---|
单引号 ' | 又叫硬转义,其内部所有的shell 元字符、通配符都会被当作普通字符。注意,硬转义中不允许出现 ' (单引号)。 |
双引号 " | 又叫软转义,其内部只允许出现特定的 shell 元字符:$ 用于参数代换 ,反引号` 用于命令代替 |
反斜杠\ | 又叫转义,去除其后紧跟的元字符或通配符的特殊意义。 |
反引号 和 $() 是一样的。在执行一条命令时,会先将反引号中或者是 $() 中的语句当作命令执行一遍,再将结果加入到原命令中重新执行,例如:
echo `ls`bash会先执行 ls ,假设得到的是 xx.sh,那么最后执行 echo xx.sh。
假设我们要匹配 html 文件中的 lang 为 en 或 zh 的行,那么我们可以用这样的正则 lang="(en|zh)" ,如果我们的正则表达式中没有出现单引号,那么在shell中用单引号包裹我们的正则表达式是最方便的一种做法 'lang="(en|zh)"',单引号意味着其中的所有字符都被shell当作普通字符来处理。 但是如果你的html中都是用的单引号 <html lang='en'>,那么用单引号shell就无法解析命令了,这个时候用双引号来代替原来的单引号,"lang='(en|zh)'" 来执行,需要注意的是如果使用双引号的话,$ 和 ` 不是普通字符,所以要在前面加上 \ 转义。
或者还有一种方法,就是不用引号,所有的元字符全部用反斜杠转义,lang=\'\(en\|z。h\)\',这样也可以匹配到正确的文本,但是如果正则表达式比较负责,这样做就有点麻烦。
总结#
因为正则表达式并没有一个统一的标准,所以在不同的环境和需求中实现都不相同,了解当前语言或者环境下正则表达式的语法是使用前必须要做的,比如在 emacs 中使用正则表示不能像 Perl正则表达式 中直接使用 ()和| 都需要用 \ 进行转义。