【问题标题】:extract filename out of raw data using regex使用正则表达式从原始数据中提取文件名
【发布时间】:2020-09-22 20:49:47
【问题描述】:

这是我的原始数据:

h24-71-249-14.ca.shawcable.net - - [07/Mar/2004:22:29:13 - 0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049

h24-71-249-14.ca.shawcable.net - - [07/Mar/2004:22:29:13 - 0800] "GET /icons/gnu-head-tiny HTTP/1.1" 200 3049

我希望能够从 URI 中提取文件名(如果有,如果没有 - 忽略)。文件可以是任何文件类型(jpg、png、txt 等)

这是我目前所拥有的:

(\"+)(.*?)(\.\w{1,3})

我知道从" 开始我的字符串可能不是一个好主意,这可能是我的问题的原因,所以我想获得一些帮助来修复我的正则表达式。

谢谢!

【问题讨论】:

  • 您只想要 GET 和 HTTP 之间的内容吗?然后只需 /GET\s*([^\s\.]*\.\S*)\s*HTTP/ 并保存您的捕获组
  • 另外,有语言要求吗?
  • 获取没有最后一个点和1-3个单词字符的文件名"GET \S+/(\S+)\.\w{1,3}regex101.com/r/AT2y7x/1

标签: regex splunk


【解决方案1】:

你可以从"开始模式,但你不必逃避、重复和捕捉它。

如果您希望扩展名与文件名一起使用,您可以使用单个捕获组。

你可能会使用:

"GET \S+\/(\S+\.\w{1,3})\b

说明

  • "GET 字面匹配
  • \S+/ 匹配 1+ 个非空白字符,然后匹配最后一个 /
  • (\S+\.\w{1,3}) 捕获组 1,匹配 1+ 个非空白字符、一个点和 1-3 个单词字符
  • \b一个字边界

Regex demo

没有标记语言,但例如使用 Javascript

const regex = /"GET \S+\/(\S+\.\w{1,3})\b/;
[
  "h24-71-249-14.ca.shawcable.net - - [07/Mar/2004:22:29:13 - 0800] \"GET /icons/gnu-head-tiny.jpg HTTP/1.1\" 200 3049",
  "h24-71-249-14.ca.shawcable.net - - [07/Mar/2004:22:29:13 - 0800] \"GET /icons/gnu-head-tiny HTTP/1.1\" 200 3049"
].forEach(s => {
  let m = s.match(regex);
  if (m) console.log(m[1]);
})

当支持\K 时,您只能获取匹配项。根据 cmets,此模式获得特定的所需匹配:

\w{1,5} \S+\/\K\S+\.\w{3}\b

说明

  • \w{1,5} 匹配 1-5 个单词字符和一个空格
  • \S+\/ 匹配 1+ 个非空白字符,然后是最后一个 /
  • \K重置匹配缓冲区(忘记匹配到现在)
  • \S+ 匹配 1+ 个非空白字符
  • \.\w{3}匹配一个点和1-3个单词的字符
  • \b一个字边界

Regex demo

【讨论】:

  • 谢谢!但是这个正则表达式的捕获与我的正则表达式捕获的相同。我只想捕获文件名,意思是:“gnu-head-tiny.jpg”(来自第一条日志行)
  • @orsa 你必须得到 rhe 组 1 值 regex101.com/r/L5T2iQ/1 工具或语言是什么?
  • 我正在尝试在 SPLUNK 中创建一个名为“file_name”的新字段
  • @orsa 像这样尝试仅获得匹配项"GET \S+\/\K\S+\.\w{1,3}\b regex101.com/r/LW1PMT/1
  • 非常感谢!如果我不想从“GET”开始怎么办?(因为在日志列表中也有 POST 日志)
【解决方案2】:

这里有两个选项:

首先

如果您想要 GET HTTP 之间的内容,可以这样做:

| rex field=_raw "GET\s+(?<fname>\S+)\s+HTTP"

从字符串文字GET 开始,输入一个(或多个)空格,然后将所有空格字符(直到以字符串文字HTTP 结尾的空格序列) ) 进入新字段fname

从功能上讲,您可以从正则表达式中删除 \s+HTTP,但为了完整,您可能希望选择将其保留在那里。

第二

如果你只想要结束文件名,就是这样:

| rex field=_raw "(?<fname>[\.\-\w]+)\s+HTTP"

这将匹配 .- 和任何单词字符 (\w) 的所有实例,其次数与在一系列空白字符 (\s+) 后跟字符串文字 @ 之前找到的次数相同987654333@ 进入新字段fname

或者,可选(虽然找到匹配项的步骤更多,但在您的情况下可能会更好):

| rex field=_raw "(?<fname>[^\/]+)\s+HTTP"

这将匹配任何不是正斜杠 (/) 的内容,直到一系列空格,然后是 HTTP,所有这些都进入新字段 fname

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多