我正在玩正则表达式组织,并且遇到困扰我的事情。鉴于以下内容:
TestEko:::Test
TestEko::Test
我无法匹配冒号组。我尝试了以下内容:
\(::\|:::\) # only matches ::
\(:\{2,3\}\) # only matches ::
\(::\+\) # only matches ::
那么,我如何匹配第一行的:::
和第二行的::
?
答案 0 :(得分:0)
如果您想匹配任意数量的冒号,请尝试使用以下表达式
s/(:)+/*/g
这会将任意数量的冒号替换为*
您的输出将是
TestEko* Test
TestEko* Test
答案 1 :(得分:0)
这可能适合你(GNU sed):
sed 's/:::\?/X&X/' file # should print TestEkoX:::XTest and TestEkoX::XTest
答案 2 :(得分:0)
每个工具处理正则表达式的方式略有不同。甚至sed也有不同的方式,因为有多种sed实现。
如果您使用的是Linux,那么您可能正在运行GNU sed,它可以随心所欲地完成您的工作:
$ printf 'one::two\nthree:::four\n' | sed 's/:::\?/_/'
one_two
three_Four
然而,在FreeBSD中,你使用的是BSD sed,它与GNU的工作方式不同。在FreeBSD中,以下工作(类似于你的一次尝试):
$ printf 'one::two\nthree:::four\n' | sed 's/:\{2,3\}/_/'
one_two
three_four
当然,如果您使用Extended RE而不是sed的默认Basic RE表示法,所有这些都会被简化。 (您可以man re_format
了解有关此内容的更多信息。)
在Linux和FreeBSD中,这有效:
$ printf 'one::two\nthree:::four\n' | sed -r 's/:::?/_/'
one_two
three_four
在FreeBSD和OSX中,这有效:
$ printf 'one::two\nthree:::four\n' | sed -E 's/:::?/_/'
one_two
three_four
是的,FreeBSD支持扩展RE的-r
和-E
。 -E
选项是在几年前引入的,OSX使用BSD源代码作为自己的版本。为了与GNU sed兼容,FreeBSD的后续版本添加了-r
,但OSX尚未采用该版本。
当然,我应该指出,所有这些都受到影响,因为它们并非固定在任何一方的非冒号字符上。从技术上讲,如果您只搜索::
,则还会匹配:::
:
printf 'one::two\nthree:::four\n' | sed -r 's/::/_/'
one_two
three_:four
所以你需要一些方法来识别“非冒号”字符。你不能使用单词分隔符([[:<:]]
和[[:>:]]
),因为这不是单词边界,但这应该有效:
$ printf 'one::two\nthree:::four\nfive::::six\n' | sed -r 's/([^:])(:::?)([^:])/\1_\3/'
one_two
three_four
five::::six
即使在BRE中:
printf 'one::two\nthree:::four\nfive::::six\n' | sed 's/\([^:]\):\{2,3\}\([^:]\)/\1_\2/'
one_two
three_four
five::::six
这有帮助吗?