V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
tanteng
V2EX  ›  NGINX

如何在 nginx 用正则表达式提取内容?

  •  
  •   tanteng ·
    tanteng · 2016-10-09 18:51:15 +08:00 · 4111 次点击
    这是一个创建于 2967 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如我把本地浏览器 UA 改成了 Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 name 也就是在后面加个空格和 name

    在 nginx 的配置文件中,我想提取$http_user_agent 中最后这个加的 name

        if ($http_user_agent ~ (这里正则表达式) {
            set $user "$user";
        }
    

    这里正则表达式怎么写,或者如何提取$http_user_agent 的后面一个空格和空格后面的 name 呢? 求指教!

    第 1 条附言  ·  2016-10-10 14:29:02 +08:00

    在http域中使用map正则匹配:

    map $http_user_agent $user {
        default            '';
        ~curl              curl;
        ~(?<name>[\S]+$)   $name;
    }
    

    在server中测试:

    location /hello {
        echo http_user_agent:$http_user_agent;
        echo user:$user;
    }
    
    

    使用 curl 请求,输出 curl 使用浏览器修改UA,在UA后面加空格和名字,如:

    Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 name ,输出 name

    要的就是这个效果。

    能捕捉这个name,可以做好多事情,如一台测试机可以支持多目录拉取网站代码,每个测试通过修改UA+自己名字,访问的是各自的目录。

    第 2 条附言  ·  2016-10-10 15:26:33 +08:00
    12 条回复    2016-10-10 14:29:22 +08:00
    tanteng
        1
    tanteng  
    OP
       2016-10-09 19:11:38 +08:00
    比如 Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 tanteng 这个 User-Agent ,用正则 /[ ]([\S]+)/ 可以匹配所有空格+非空格内容,这样会匹配到多个内容,但是 nginx 里怎么取出匹配到的最后一个。
    qq286735628
        2
    qq286735628  
       2016-10-09 19:21:50 +08:00   ❤️ 1
    /[\S]+$/
    查找结尾处非空白字符
    qq286735628
        3
    qq286735628  
       2016-10-09 19:22:23 +08:00
    推荐个学习正则的网站
    https://www.debuggex.com/
    honk
        4
    honk  
       2016-10-09 19:58:10 +08:00 via Android
    不要直接加 name ,换成 username/xxx , xxx 就是动态的 name
    yangg
        5
    yangg  
       2016-10-09 20:57:59 +08:00   ❤️ 1
    location /echo {
    set $user '';
    if ($http_user_agent ~ (?<user>\S+)$ ) {
    set $user "$user";
    }
    return 200 $user;
    }
    lHUAC
        6
    lHUAC  
       2016-10-09 21:16:35 +08:00
    下面代码,已测试通过。:)
    if ($http_user_agent ~* "\b(?'baobao'\S\w+$)") {
    set $user "$baobao";
    }
    lHUAC
        7
    lHUAC  
       2016-10-09 21:19:44 +08:00   ❤️ 1
    再测试一遍。成功, LZ 可以测试下
    if ($http_user_agent ~* "\b(?'baobao'\S\w+)$") {
    set $user "$baobao";
    }
    lhbc
        8
    lhbc  
       2016-10-09 21:44:16 +08:00   ❤️ 1
    楼主你这个需求强烈建议用 map 指令,不要用 if
    ryd994
        9
    ryd994  
       2016-10-10 02:40:56 +08:00 via Android   ❤️ 1
    if 会降低性能并导致各种奇奇怪怪的问题
    用 map
    tanteng
        10
    tanteng  
    OP
       2016-10-10 13:48:11 +08:00
    map 形式怎么写
    ```
    map $http_user_agent $user {
    default '';
    ~curl curl;
    ~[\S]+$ $user;
    }
    ```

    这样只能匹配 curl ,用浏览器就直接 nginx 挂了
    tanteng
        11
    tanteng  
    OP
       2016-10-10 14:00:44 +08:00
    @tanteng 我这样写,通过浏览器进来的就直接挂了,但 curl 方式是 OK 的,[alert] 804#804: worker process 5083 exited on signal 11
    tanteng
        12
    tanteng  
    OP
       2016-10-10 14:29:22 +08:00
    找到解决方法了,对 nginx 不太熟悉,现在 OK 了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2702 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:41 · PVG 18:41 · LAX 02:41 · JFK 05:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.