Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 删除一个字符的单词_Regex_Bash_Perl_Awk_Sed - Fatal编程技术网

Regex 删除一个字符的单词

Regex 删除一个字符的单词,regex,bash,perl,awk,sed,Regex,Bash,Perl,Awk,Sed,我正在寻找一个regexp来删除一个字符的单词。我不介意是使用perl、awk、sed还是bash内置 测试用例: $ echo "a b c d e f g h ijkl m n opqrst u v" | $COMMAND 期望输出: ijkl opqrst 到目前为止,我所尝试的: $ echo "a b c d e f g h ijkl m n opqrst u v" | sed 's/ . //g' acegijkln opqrstv 我猜: a不会被删除,因为它前面没有空格

我正在寻找一个regexp来删除一个字符的单词。我不介意是使用
perl
awk
sed
还是
bash
内置

测试用例:

$ echo "a b c d e f g h ijkl m n opqrst u v" | $COMMAND
期望输出:

ijkl opqrst
到目前为止,我所尝试的:

$ echo "a b c d e f g h ijkl m n opqrst u v" | sed 's/ . //g'
acegijkln opqrstv
我猜:

  • a
    不会被删除,因为它前面没有空格
  • c
    保持不变,因为一旦删除了
    b
    ,前面就没有空白了
  • 等等
尝试#2:

在这里,我根本不知道发生了什么


欢迎任何帮助+解释,我想学习。

您必须使用单词边界
\b
(或)
\
分别匹配单词开头和结尾的空字符串

echo "a b c d e f g h ijkl m n opqrst u v" | sed 's/\b\w\b \?//g'
$ awk '{while(sub(/^[^ ] | [^ ]$/,"")||sub(/ [^ ] /," "));}1'
(或)

echo“a b c d e f g h ijkl m n opqrst u v”| sed's/\\?//g'

您可以简单地使用
grep

echo "a b c d e f g h ijkl m n opqrst u v"  | grep -o '[a-z]\{2,\}'
其中正则表达式匹配由至少2个字符组成的任何单词


grep
中的
-o
选项打印匹配的模式(而不是整行)。

尽管
Awk
不是最有效的方法,只是因为它使用了
length()
字符串函数进行了标记才进行应答。它符合POSIX标准,因此在可移植性方面没有问题

echo "a b c d e f g h ijkl m n opqrst u v" | \
  awk '{for(i=1;i<=NF;i++) {if (length($i)>1) { printf "%s ", $i }} }'
ijkl opqrst
echo“a b c d e f g h ijkl m n opqrst u v”|\
awk'{for(i=1;i1){printf“%s”,$i}'
ijkl opqrst

Perl解决方案:只需在


由于不熟悉任何linux Spring工具,这有点像猜测,但我认为您想要的(a)regex是

(?:\s\w\b|\b\w\s)

这将替换前面有空格或被空格愚弄的任何单个字符


.

awk中的另一个。非空格(
[^]
)被视为单词。你可以随意用你对一个词的定义来代替它

echo "a b c d e f g h ijkl m n opqrst u v" | sed 's/\b\w\b \?//g'
$ awk '{while(sub(/^[^ ] | [^ ]$/,"")||sub(/ [^ ] /," "));}1'
使用
sub
[a space][non space][a space]
元组替换为空格 并从记录的开头和结尾删除单个字符和前导/尾随空格。它在
中,而
中,所以它会一直这样做,直到没有点击为止。要测试它,请执行以下操作:

$ echo "a b c d e f g h ijkl m n opqrst u v"|awk '{while(sub(/^[^ ] | [^ ]$/,"")||sub(/ [^ ] /," "));}1'
ijkl opqrst

为了好玩,另一个选择是:将空格转换为换行符,并查找至少包含2个字符的行

$ echo "a b c d e f g h ijkl m n opqrst u v" | tr ' ' '\n' | grep .. | paste -sd " "
ijkl opqrst

我不同意,我的帖子中有一个特定的问题。@nicoco,你可以试试单词边界(
\b
)。@nicoco这不是问题。“喂,这看起来像是一个“给我密码贴”。@Biffen:我不同意。OP已经为他们的问题写了一个解决方案,并且正在寻求帮助以使其工作。在“长”字之前留下了很多空白,但我可以解决这个问题。谢谢@nicoco您也可以使用
s/\b\w\b?//g
来删除whispaces。使用
\b
时要非常小心:您所拥有的将冲击诸如“will-o'-thewisp”和“Build-A-Bear”之类的东西。或者使用GNU awk的相同解决方案:
awk'{gsub(/\?/,“)}1'
。你可以使用
grep-E
,这样你就不需要那些讨厌的反斜杠了。应该注意的是,这会用换行符分隔所有匹配项,而换行符与问题中所写的期望输出不完全相同。这可能是问题,也可能不是问题,取决于具体情况。在这种情况下,使用
-w
导入
|paste-sd”“
,您不需要
\b
锚。如果您想更简洁一些,可以省略默认变量:
grep{length>1}@F
您不应该说
awk不是最有效的方法….
,只是你发布的特定awk代码不是最有效的方式。@EdMorton:正如你所说的Ed!也许你可以纠正我的逻辑,或者提供一种更有效的方法。我在答案下面添加了与公认答案相当的awk,请参见@EdMorton:好吧!在
awk
sed-r的/(\s\w\b |\b\w\s)//g中,每个人都不能和Ed Morton在同一个班级里回答
$ awk '{while(sub(/^[^ ] | [^ ]$/,"")||sub(/ [^ ] /," "));}1'
$ echo "a b c d e f g h ijkl m n opqrst u v"|awk '{while(sub(/^[^ ] | [^ ]$/,"")||sub(/ [^ ] /," "));}1'
ijkl opqrst
$ echo "a b c d e f g h ijkl m n opqrst u v" | tr ' ' '\n' | grep .. | paste -sd " "
ijkl opqrst