1,空格表示方式
[[:space:]]+
[[:blank:]]+
' +' (这个是一个空格一个加号+) \s+ \s \s. \s*
如何替换一个以上连续的空格为一个指定字符?
假设给定的字符串是这样的 :
"LEG1 Height; LEG2 CYL DIS1; TIME"
有以下几种解决方案,格式如下,直接复制进来套可以看输出效果,文件的话替换成指定的文件名字也行
2,solution
echo "LEG1 Height; LEG2 CYL DIS1; TIME" | sed -E "s/\s+/_/g; s/; s/#//g; s/\"//g"
bash
head -n 1 test.csv | sed -E "s/[[:space:]]+/_/g;s/;s/#//g;s/\"//g"
head -n 1 test.csv | sed -E "s/[[:blank:]]+/_/g; s/; s/#//g; s/\"//g"
head -n 1 test.csv | sed -E "s/ +/_/g; s/; s/#//g; s/\"//g"
head -n 1 test.csv | sed -E "s/\s+/_/g; s/; s/#//g; s/\"//g"
head -n 1 test.csv | sed -E "s/\s./_/g; s/; s/#//g; s/\"//g"
3,符号的含义
-
\s
- 表示匹配空白字符(包括空格、制表符、换行符等)。
- 如果不带其他量词(如
*
或+
),则只匹配单个空白字符。
-
.
- 表示匹配任意单个字符(除换行符外)。
- 仅匹配一个字符,不会连续匹配多个。
-
*
- 匹配前面的字符(或字符集)的零次或多次。
- 例如:
a*
匹配空字符串、a
、aa
等。\s*
匹配零个或多个空白字符(包括完全没有空格的情况)。
-
+
- 匹配前面的字符(或字符集)的至少一次(即一到多次)。
- 例如:
a+
匹配a
、aa
等,但不匹配空字符串。\s+
匹配一个或多个连续的空白字符。
-
?
- 匹配前面的字符(或字符集)的零次或一次。
- 例如:
a?
匹配空字符串或a
。
-
以上解决方案中满足需求的是前4个,1个以上连续空格替换为指定的下划线。如果字符串中只有两个空格,那么最后一个碰巧也满足
4,实际的问题
1. 有两个空格,为什么 s/\s+/_/g
和 s/\s./_/g
的效果一样?
文件内容是 LEG1 Height varchar(255)
(有两个空格),操作后变成 LEG1_Height varchar(255)
。
-
\s+
- 匹配一个或多个连续的空白字符。
- 两个空格被视为连续的空白字符,因此整个匹配被替换为下划线
_
。
-
\s.
- 匹配一个空白字符(
\s
)后跟一个任意字符(.
)。 - 匹配的结果是第一个空格和其后一个字符 ,即:匹配
␣H
(空格 +H
)。 - 替换时,只保留了后续未被匹配的内容。
- 匹配一个空白字符(
区别在于:
- 对于连续多个空格,
\s+
会整体匹配并替换,而\s.
只会替换一次,替换的范围是第一个空格及其后一个字符。 - 在您的文件内容中,替换结果一样是因为替换的具体情况不复杂(两个空格在这种场景中等价处理)。
2. 为什么用 *
会影响没有空格的内容?
-
\s*
匹配零个或多个空白字符:- 即使某处没有空格,
\s*
也能匹配零个空格(空字符串)。 - 例如:
- 输入:
LEG1Height
- 替换:
s/\s*/_/g
会在每个字符之间插入下划线,结果为:_L_E_G_1_H_e_i_g_h_t_
。
- 输入:
- 即使某处没有空格,
-
\s+
匹配一个或多个空白字符:- 如果没有空格的地方,
\s+
不会匹配,因此不会替换没有空格的内容。
- 如果没有空格的地方,
总结:量词的适用场景
-
\s*
(零次或多次):- 会匹配空白字符,也会匹配空字符串,适用于希望尽量覆盖所有情况(即使没有空格的地方)。
- 常用场景:在任意字符间添加标记。
-
\s+
(至少一次):- 只匹配一个或多个连续的空白字符,不匹配没有空格的地方。
- 常用场景:替换有空格分隔的内容。
-
\s.
(空格 + 任意字符):- 严格匹配特定模式,适用于仅替换空格后紧跟的内容。