这是什么蟒蛇皮呢?

时间:2018-07-17 00:50:10

标签: python scripting

您将如何在python中执行此操作? (它会遍历一个文件,并在author“:”,“ and text”:“,\之间打印字符串,然后将它们打印到他们的文件中)

在此之前,这里是一个示例字符串:

{"text": "Love this series!\ufeff", "time": "Hace 11 horas", "author": "HasRah", "cid": "UgyvXmvSiMjuDrOQn-l4AaABAg"}

#!/bin/bash
cat html.txt | awk -F 'author": "' {'print $2'} | cut -d '"' -f1 >> users.txt
cat html.txt | awk -F 'text": "' {'print $2'} | cut -d '\' -f1 >> comments.txt

我试图在python中这样做(无效):

import re

start = '"author": "'
end = '", '

st = open("html.txt", "r")
s = st.readlines()

u = re.search('%s(.*)%s' % (start, end), s).group(1)
#print u.group(1)

不确定我是否要关闭

我收到此错误代码:

Traceback (most recent call last):
 File "test.py", line 9, in <module>
   u = re.search('%s(.*)%s' % (start, end), s).group(1)
 File "/usr/lib/python2.7/re.py", line 146, in search
   return _compile(pattern, flags).search(string)
TypeError: expected string or buffer`

1 个答案:

答案 0 :(得分:1)

在进行以下任何操作之前:正如chepner在评论中指出的那样,此输入看起来像JSON,因此可能是JSON。这意味着您不应该使用正则表达式对其进行解析;只需将其解析为JSON:

>>> s = ''' {"text": "Love this series!\ufeff", "time": "Hace 11 horas", "author": "HasRah", "cid": "UgyvXmvSiMjuDrOQn-l4AaABAg"}'''
>>> obj = json.loads(s)
>>> obj['author']
'HasRah'

实际上,尚不清楚您的输入是JSON文件(包含一个JSON文本的文件)还是JSONlines文件(包含一堆行的文件,其中每行都是没有嵌入换行符的JSON文本)。 1

对于前者,您想要这样解析:

obj = json.load(st)

对于后者,您希望遍历所有行,并像这样解析每行:

for line in st:
    obj = json.loads(line)

...,或者,您也可以从PyPI获得JSONlines库。


但是,与此同时,如果您想了解代码出了什么问题,

错误消息告诉您问题所在,尽管可能不是用户友好的方式:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/re.py", line 148, in search
    return _compile(pattern, flags).search(string)
TypeError: expected string or bytes-like object

请参阅search的文档以明确说明:

re.search(pattern, string, flags=0)
  

扫描 string 来查找正则表达式 pattern 产生匹配项的第一个位置,然后返回相应的MatchObject实例…

您没有向其传递字符串,而是向其传递了字符串列表。毕竟,这就是readlines的重点。


这里有两个明显的解决方法。

首先,您可以将整个文件读取为一个字符串,而不是将其读取为字符串列表:

s = st.read()
u = re.search('%s(.*)%s' % (start, end), s).group(1)

或者,您可以遍历所有行,尝试匹配每行。而且,如果您执行此操作,则您仍然不需要readlines(),因为文件已经已经是可重复的行了:

for line in st:
    u = re.search('%s(.*)%s' % (start, end), line).group(1)

我们正在处理中,如果您的任何行与模式都不匹配,这将引发AttributeError。毕竟,如果没有匹配项,search返回None,但是您将尝试调用None.group(1)

这里也有两个明显的修复。

您可以处理该错误:

try:
    u = re.search('%s(.*)%s' % (start, end), line).group(1)
except AttributeError:
    pass

…或者您可以检查是否有匹配项:

m = re.search('%s(.*)%s' % (start, end), line)
if m:
    u = m.group(1)

1。实际上,至少还有其他两种格式与JSONlines几乎相同,但并不完全相同。我认为,如果您只关心阅读而不是创建文件,并且没有任何数字,则可以使用json.loads周围的循环或JSONlines库来解析所有文件。但是,如果您知道是谁创建了该文件,并且知道他们打算将其作为NDJ而不是JSONlines,则应该阅读NDJ上的文档,或者为NDJ创建一个库,而不是仅仅相信那个家伙。互联网认为可以将其视为JSONlines。