捕获两个令牌之间的文本

时间:2016-02-20 04:32:52

标签: regex bash sed

我正在尝试在两个令牌之间获取文本。

例如,假设文字是:

arn:aws:dfasdfasdf/asdfa:start:CaptureThis/end

输出应为:CaptureThis

这两个令牌是::start:/end

我最接近的是使用正则表达式

INPUT="arn:aws:dfasdfasdf/asdfa:start:CaptureThis/end"
VALUE=$(echo "${INPUT}" | sed -e 's/:start:\(.*\)\/end/\1/')

...但这会返回大部分字符串:arn:aws:dfasdfasdf/asdfa:start:CaptureThis/end

如何将所有其他文字排除在外?

4 个答案:

答案 0 :(得分:3)

你可以使用(GNU)grep和Perl正则表达式(环顾四周)和-o选项来只返回匹配:

$ grep -Po '(?<=:start:).*(?=/end)' <<< 'arn:aws:dfasdfasdf/asdfa:start:CaptureThis/end'
CaptureThis

答案 1 :(得分:2)

试试这个:

public class Exchange {
    public static void main(String[] args) {
    //int a = 23, b = 44;
    byte a = 23, b = 44;
    a = (byte) a + b;
    b = (byte) a - b;
    a = (byte) a - b;
    System.out.println("a=" + a + "b=" + b);
    }
}

您的方法存在的问题是您只替换了输入行的部分,因为您的正则表达式没有捕获整个行。

注意上面的命令如何在行的开头($ sed 's/^.*:start:\(.*\)\/end.*$/\1/' <<<'arn:aws:dfasdfasdf/asdfa:start:CaptureThis/end' CaptureThis )和结尾(^.*)处锚定正则表达式,以确保整个行匹配并因此被替换。

答案 2 :(得分:2)

您可以使用:

VALUE=$(echo "${INPUT}" | sed -e 's/.*:start:\(.*\)\/end.*/\1/')

如果令牌易于改变,你可以使用变量 - 但是因为&#34; / end&#34;有一个&#34; /&#34;,这可能导致sed感到困惑,所以你可能想要将它的分隔符更改为一些非冲突的角色(比如&#34;?&#34; ),所以:

TOKEN1=":start:"
TOKEN2="/end"
VALUE=$(echo "${INPUT}" | sed -e "s?.*$TOKEN1\(.*\)$TOKEN2.*?\1?")

答案 3 :(得分:2)

不需要任何外部工具,bash 参数扩展将为您处理所有这些:

INPUT="arn:aws:dfasdfasdf/asdfa:start:CaptureThis/end"
token=${INPUT##*:}
echo ${token%/*}

<强>输出

CaptureThis