所以我非常擅长使用正则表达式,但在 unix 上使用它们时遇到了一些麻烦。以下是我想知道如何做的两件事:
1) 替换除字母、数字和下划线以外的所有文本
在 PHP 中我会这样做:(效果很好)
preg_replace('#[^a-zA-Z0-9_]#','',$text).
在 bash 中我尝试了这个(成功有限);似乎它不允许您使用整套正则表达式:
text="my #1 example!" ${text/[^a-zA-Z0-9_]/'')
我用 sed 试过了,但它似乎仍然对完整的正则表达式集有问题:
echo "my #1 example!" | sed s/[^a-zA-Z0-9\_]//
我敢肯定也有一种方法可以用 grep 做到这一点,但是当我尝试时它把它分成多行:
echo abc\!\@\#\$\%\^\&\*\(222 | grep -Eos '[a-zA-Z0-9\_]+'
最后我也尝试使用 expr 但它似乎对扩展正则表达式的支持真的有限......
2) 捕获(多个)文本部分
在 PHP 中我可以做这样的事情:
preg_match('#(word1).*(word2)#',$text,$matches);
我不确定这在 *nix 中如何实现...
最佳答案
第 1 部分
你几乎已经有了 sed
只需添加 g
修饰符,这样替换就会在全局发生,没有 g
,替换就会发生就一次。
$ echo "my #1 example!" | sed s/[^a-zA-Z0-9\_]//g
my1example
$
您在替换 bash 模式时也犯了同样的错误:没有在全局范围内进行替换:
$ text="my #1 example!"
# non-global replacement. Only the space is delete.
$ echo ${text/[^a-zA-Z0-9_]/''}
my#1 example!
# global replacement by adding an additional /
$ echo ${text//[^a-zA-Z0-9_]/''}
my1example
第 2 部分
捕获在 sed
中的工作方式与在 PHP 的正则表达式中相同:将模式括在括号中会触发捕获:
# swap foo and bar's number using capturing and back reference.
$ echo 'foo1 bar2' | sed -r 's/foo([0-9]+) bar([0-9]+)/foo\2 bar\1/'
foo2 bar1
$
关于regex - unix/linux 上的 grep : how to replace or capture text?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4766546/