【问题标题】:Processing delimiters with python用python处理分隔符
【发布时间】:2015-08-17 04:25:35
【问题描述】:

我目前正在尝试以我无法正常执行的格式解析 apache 日志。 (尝试使用 goaccess)

在崇高的情况下,分隔符显示为 ENQ、SOH 和 ETX,我的理解也是“|”、空格和上标 L。我试图使用 re.split 来分隔日志的各个组件,但我'不知道如何处理上标 L。

在 sublime 上显示为 3286d68255beaf010000543a000012f1/Madonna_Home_1.jpgENQx628a135bENQZ1e5ENQAB50632SOHA50.134.214.130SOHC98.138.19.91SOHD42857ENQwwww.newprophecy.net...

ENQ 为 '|'当我在纯文本编辑器(如记事本)中打开文件时,SOH 为 ''

我只需要解析出 IP 地址,因此该行的其余部分几乎无关紧要。

目前我有

pkts = re.split("\s|\\|")

但我不知道L该怎么办。

【问题讨论】:

  • 带有预期输出的示例会更好。
  • 在正则表达式中复制粘贴下标L有什么问题?
  • 请举个例子,比如输入样例和输出样例。
  • 大多数网络服务器默认使用common log format。但它们通常也允许您更改它。如果可以,请选择一种日志格式,在该格式中使用通常未使用的字符作为字段分隔符。然后你可以做一个简单的split() 来获取不同的字段。
  • @AvinashRaj 添加了一个示例,我无法复制和粘贴 L,因为它默认为问号(尽管这可能是我不确定的实际字符)

标签: python regex logging extract


【解决方案1】:

这些 3 字母代码是 ASCII 控制代码 - 这些是 ASCII 字符,出现在 ASCII 字符集中的 32(空格字符)之前。你可以找到a full list online

这些字符不对应于任何可打印的字符,因此假设它们对应于这些字符是错误的。您可以使用 \x00 表示法将它们称为多种语言的文字 - 例如,控制代码 ETX 对应于 \x03(请参阅上面链接到的参考资料)。您可以使用这些来拆分字符串或其他任何内容。

这是您问题的字面答案,但除此之外,我发现您实际上不太可能需要通过控制代码拆分您的 Apache 日志文件。猜测实际发生的情况可能是 som Unicode 字符以某种方式潜入了您的日志文件,可能是 UTF-8 编码。编码是一种表示超出单个字节 255 个限制的字符的方法,它通过对具有多个字节的扩展字符进行编码。

有多种编码类型,但 UTF-8 是最流行的一种。如果您使用 UTF-8,它具有标准 ASCII 字符将正常显示的属性(因此您甚至可能永远不会意识到正在使用 UTF-8),但是如果您在不是 UTF-8 的编辑器中查看文件知道(或错误地将文件识别为纯 ASCII),那么您将看到这些奇怪的控制代码。这些地方实际上应该将代码和它之前或之后的字符一起解释为一个单元。

我不确定这是不是这个原因,这只是一个有根据的猜测,但如果你还没有考虑过,那么弄清楚文件的编码很重要,因为它会影响你如何解释整个文件它的内容。我建议将文件加载到理解编码的编辑器中(我确信像 Sublime 一样流行的东西在适当的配置下)并强制编码为 UTF-8,看看这是否会使内容看起来更合理。

【讨论】:

  • 那么有没有办法将它们作为字符串处理?当我尝试在 python 中读取时,它给出了错误“codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x90” 这意味着编码没有指定,但我我之前打开文件的时候有,所以我不知道该怎么做。
  • 0x90 对我来说听起来像是一个 UTF-8 延续字节。我认为该错误意味着使用了charmap编码-错误来自哪个源文件?例如,cp1252.py 是 Windows 上的常见罪魁祸首。源文件可能会告诉您正在使用哪种编码。如果您想尝试 UTF-8,请像这样打开文件:fd = open(filename, encoding="utf8")
  • (如果您使用的是 Python 2,请改用 codecs.open())。
  • 我得到了要读取的文件(另一个函数的问题),但是我似乎仍然无法正确拆分字符串。这是一个示例字符串图片的链接i.imgur.com/11KZfDS.png(无法发布图片没有足够的代表)我不确定此时我将如何拆分它。
  • 在我看来,这些字符并不是您想要拆分的内容 - 我认为如果您使用正确的编码读取文件,那么您可能根本不会得到这些字符,并且我个人的怀疑是这对你来说是更好的解决方案。如果您只是拆分原始字符串,我认为您还会遇到其他问题,例如分隔符和内容之间的混淆。然而,如果你真的想分开,比如说,ENQ,那么试试my_string.split('\x05')——这对你有用吗?您可以使用我在答案中链接到的列表找到其他代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 1970-01-01
  • 2013-08-17
  • 2015-11-07
相关资源
最近更新 更多