'\ K'在这个正则表达式中意味着什么?

D-K*_*otz 25 regex bash grep

鉴于以下shell脚本,有人会如此善良地解释grep -Po正则表达式吗?

#!/bin/bash
# Issue the request for a bearer token, json is returned
raw_json=`curl -s -X POST -d "username=name&password=secret&client_id=security-admin-console" http://localhost:8081/auth/realms/master/tokens/grants/access`
# Strip away all but the "access_token" field's value using a Python regular expression
bearerToken=`echo $raw_json | grep -Po '"'"access_token"'"\s*:\s*"\K([^"]*)'`
echo "The bearer token is:"
echo $bearerToken
Run Code Online (Sandbox Code Playgroud)

具体来说,我有兴趣了解正则表达式的各个部分

grep -Po '"'"access_token"'"\s*:\s*"\K([^"]*)'`
Run Code Online (Sandbox Code Playgroud)

以及它是如何工作的.为什么这么多报价呢?什么是"K"?我有一些grep正则表达式的经验,但这让我很困惑.

这是curl命令的实际输出,shell脚本(grep)按需运行,只返回"access_token"值的内容.

{ "的access_token": "fQmQKn-xatvflHPAaxCfrrVow3ynpw0sREho7__jZo2d0g1SwZV7Lf4C26CcweNLlb3wmKHHo63HRz35qRxJ7BXyiZwHgXokvDJj13yuOb6Sirg9z02n6fwGy8Iog30pUvffnDaVnUWHfVL-h_R4-OZNf-_YUK5RcL2DHt0zUXI.", "expires_in":60, "refresh_expires_in":1800, "refresh_token": "eyJhbGciOiJSUzI1NiJ9..WeiJOC1jQ52aKgnW8UN2Lv9rJ_yKZiOhijOYKLN2EEOkYF8rvRZsSKbTPFKTIUvjnwy2A7V_N-GhhJH4C-T7F5__QPNofSXbCNyvATj52jGLxk9V0Afvk-Z5QAWi55PJRTC0qteeMRcO2Frw-0KtKYe9o3UcGICJubxhZHsXBLA"," token_type ":" 承载", "id_token": "eyJhbGciOiJSUzI1NiJ9.eyJuYW1lIjoiIiwianRpIjoiMGIyMGI0ODctOTI4OS00YTFhLTgyNmMtM2NiOTg0MDJkMzVkIiwiZXhwIjoxNDQ2ODI4MDU5LCJuYmYiOjAsImlhdCI6MTQ0NjgyNzk5OIwouldhaveToBeNutsUiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZX0.DmG8Lm4niL1djzNrLsZ2CrsB1ZzUPnR2Nm7IZnrwrmkXsrPxjl6pyXKCWSj6pbk2sgVI8NNFqrGIJmEJ7gkTZWm328VGGpJsmMuJBki0KbqBRKORGQSgkas_34rwzhcTE3Iki8h_YVs2vvNIx_eZSOvIzyEcP3IGHuBoxcR6W3E", "不先于政策":0, "会话状态": "62efc05c-1bf5-4f55-b749-5e0eff94155b"}


如果有人发现这篇文章,这就是我最终使用的内容:

if hash jq 2>/dev/null; then
  # Use the jq command to safely parse json
  bearerToken=$(echo $raw_json | jq -r '.access_token')
else
  # Strip away all but the "access_token" field's value using a perl regular expression
  bearerToken=$(echo $raw_json | grep -Po '"'"access_token"'"\s*:\s*"\K([^"]*)')
fi
Run Code Online (Sandbox Code Playgroud)

Mar*_*oun 52

由于不是所有正则表达式都支持lookbehind,Perl介绍了\K.一般来说,当你有:

a\Kb
Run Code Online (Sandbox Code Playgroud)

当"b"匹配时,\K告诉引擎假装在该位置开始匹配尝试.

在您的示例中,您希望假装匹配尝试在""access_token":"文本之后出现的内容开始.

此示例将更好地演示\K用法:

~$ echo 'hello world' | grep -oP 'hello \K(world)'
world
~$ echo 'hello world' | grep -oP 'hello (world)'
hello world
Run Code Online (Sandbox Code Playgroud)

  • 正则表达式有点过分引用.它以`'"'开头,它只是单引号字符串中的单个双引号.接下来是一个包含`access_token`的双引号字符串;这两个字符串简单地连接在一起.最后是单个 - 带引号的字符串包含一些双引号.外壳将三个字符串的内容连接在一起;例如,`'foo'"bar"'baz'`表示与"foobarbaz"相同的东西.整个事情可以更简单地写成''"access_token"\ s*:\ s*"\ K([^"]*)'`. (2认同)
  • 这看起来和 vim 中的 `\zs` 是一样的 (2认同)