我有一系列条目,可以用这个字符串表示:
my_string="-D-K4_NNNN_M116_R1_001.gz _D-K4_NNNN_M56_R1_001.gz R-K4_NNNN_KQ9_R1_001.gz D-K4_NNNN_M987_R1_001.gz _R-K4_NNNN_M987_R1_001.gz"
对于每个条目,我需要返回它是以“R”还是“D”开头。为了做到这一点,我需要忽略它之前的任何角色。所以,我写了这个正则表达式:
for i in $my_string; do echo $i | grep -E -o "^*?[RD]"; done
但是,对于没有字符开头的条目,这只会返回R
或D
。
如何让这个正则表达式在每种情况下返回R
或D
值,无论前面是否有字符?请记住,表达式中唯一可以“硬编码”的是要匹配的模式。
答案 0 :(得分:3)
使用参数扩展在使用grep之前删除前缀:
for i in $my_string; do echo ${i#[^RD]} | grep -o "^[RD]" ; done
或使用没有grep的简单测试(因为你已经知道每个项目都以R或D开头):
for i in $my_string; do
if [[ $i =~ ^[^D]?R ]] ; then
echo 'R'
else
echo 'D'
fi
done
答案 1 :(得分:3)
使用sed
:
sed -r 's/^.?([RD]).*$/\1/'
即
for i in $my_string; do echo $i | sed -r 's/^.?([RD]).*$/\1/'; done
更新:
以下是命令的每个部分的含义:
-r : extended regular expression, although I think -e should work but
turns out that during my testing, in order to use capturing group
in regex, I need -r. Anyway, not the main point
该脚本可以读作:
s/XXXX/YYYY/ : substitude from XXXX to YYYY
"来自" pattern(XXXX)表示:
^ : start with
.? : zero or one occurence of any character
( : start of group
[RD] : either R or D
) : end of group (which means, the group will contains either R or D
.* : any number of any character
$ : till the end
"到"模式(YYYY):
\1 : content of capture group 1 in the "from" pattern (which is the "R or D")
答案 2 :(得分:2)
这个正则表达式在我的本地测试中起作用。请试一试:
^.?[RD]
我无法想出一种只返回你想要的信的方法。我之后有一个命令来检测返回的字符串是否长于1个字符,如果是,我只返回第二个字符。
答案 3 :(得分:2)
我不是100%肯定你在问什么(我知道你想在文件名的开头只匹配R和D,不管它之前的字符,如果有的话),但我认为你应该使用lookbehind,在php中你会做
$re = "/(?<=^\S|\s\S|\s)[RD]/";
$str = "-D-K4_NNNN_M116_R1_001.gz _D-K4_NNNN_M56_R1_001.gz R-K4_NNNN_KQ9_R1_001.gz D-K4_NNNN_M987_R1_001.gz _R-K4_NNNN_M987_R1_001.gz";
preg_match_all($re, $str, $matches);
您可以看到输出here。
要在bash中使用Perl语法,您必须启用它。 https://unix.stackexchange.com/questions/84477/forcing-bash-to-use-perl-regex-engine
,可以在此处测试正则表达式答案 4 :(得分:2)
当使用修饰符'g'表示全局:(^| ).?(R|D)