如何在POSIX正则表达式中转义连字符以作为字符范围?

7

我可以帮助您翻译以下内容,涉及IT技术:

我有一个包含以下数值的CSV文件:

0.00145423,3.03795e-05

我想确认所有行都是一致的,所以我尝试使用grep查找任何意外字符,像这样...

grep '[^0-9,e\-\.]' myfile

在我的理解中,它的意思是:找到任何一个字符[],它不是数字0-9、逗号,、字母ee、连字符\-(尝试用\进行转义),或者句点\.。然而,连字符仍然可以匹配。

[编辑] 这只发生在bash/grep中,而不是在Python中:

>>> re.search("[^0-9,e\-\.]", "0.00145423,3.03795e-05")
>>> 

不完美的解决方案:
如果我将转义连字符移到末尾,则可以解决这个问题。

grep '[^0-9,e\.\-]' myfile

将转义的连字符放在0-9范围旁边会导致grep: Invalid range end错误。这是由于什么原因?是否与bash参数解析有关,还是与grep本身有关?(注:代码运行环境为bash4.3.33和grep2.21)

1
横杠符号位于字符类的中间时,将起到范围运算符的作用。 - Avinash Raj
3
@AvinashRaj,我不认为这是一个重复的问题。我试图按照两个答案所提出的方法来转义连字符,其中包括您提供的链接中的方法。 - jozxyqk
Linux的正则表达式与其他任何正则表达式引擎都不同。在某种程度上,这就像IE一样。 - simonzack
1
在 POSIX 括号表达式中,您不需要转义 .,因为将 . 放入括号表达式中意味着它是一个字面字符,并且转义 - 也没有任何作用(正如您所发现的那样)。 - Ed Morton
2个回答

11
要在字符列表中包含一个文字表达式 - 的方法是将它放在括号表达式的第一或最后位置,就像在这个答案中所示: Get final special character with a regular expression
来自 POSIX 9.3.5 RE Bracket Expression:

如果字符出现在列表的开头(如果有初始的^),或者出现在列表的末尾,或者出现在范围表达式的结束点,则该字符应被视为字面上的字符。

一些工具可能有其他的转义方式,但只需将其放在括号表达式的第一或最后即可保证安全。
请注意,- 不是唯一根据其位置在括号表达式中具有不同行为的字符。还有]^

2

请记住,- 是一个范围运算符,因此 \-\ 匹配的是范围内的任何字符 \\,这正好是一个 \

如果将其移动到结尾,它将失去作为范围的含义,这就是为什么它能够工作的原因。


啊,所以 \- 实际上不能转义连字符。还有其他的方法吗? - jozxyqk
在字符类的开头或结尾处替换@jozxyqk。 - Maroun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接