【问题标题】:What does this Perl XML filter look like in Python?这个 Perl XML 过滤器在 Python 中是什么样子的?
【发布时间】:2011-06-10 04:58:19
【问题描述】:
curl -u $1:$2 --silent "https://mail.google.com/mail/feed/atom" | perl -ne 'print "\t" if /<name>/; print "$2\n" if /<(title|name)>(.*)<\/\1>/;'

我有这个 shell 脚本,它使用用户名和密码的命令行参数获取 Atom 提要。我想知道这种类型的事情在 Python 中是否可行,如果可以,我将如何去做。 atom 提要只是普通的 XML。

【问题讨论】:

  • Perl 本身没有意义。声明print "$2\n" if /(.*)/; 说“在正则表达式中打印第二个捕获组”,但那里只有一个捕获组。永远不会有第二个匹配组...

标签: python regex perl email curl


【解决方案1】:

Python 不适合像 Perl 那样压缩一个内衬。这主要是出于三个原因:

  1. 对于 Perl,几乎在所有情况下空格都是无关紧要的。在 Python 中,空格非常重要。
  2. Perl 有一些对一行代码有用的快捷方式,例如perl -neperl -pe 在代码行周围放置一个implicit loop
  3. 有一个large body a cargo-cultPerl 的一个内衬可以做有用的事情。

总而言之,这个 python 和你在 Perl 中发布的很接近:

curl -u $1:$2 --silent "https://mail.google.com/mail/feed/atom" | python -c ' 
import sys
for s in sys.stdin:
    s=s.strip()
    if not s: print '\t',
    else: print s
' 

要做得更好有点困难,因为正如我在评论中所述,您发布的 Perl 是不完整的。你有:

perl -ne 'print "\t" if //; print "$2\n" if /(.*)/;'

相当于:

LINE:
while (<>) {
  print "\t" if //;         # print a tab for a blank line
  print "$2\n" if /(.*)/;   # nonsensical. Print second group but only 
                            # a single match group defined...
}

编辑

虽然在 Python 中重写 Perl 是微不足道的,但这里有一些更好的东西:

#!/usr/bin/python
from xml.dom.minidom import parseString
import sys

def get_XML_doc_stdin(f):
    return xml.dom.minidom.parse(f)

def get_tagged_data2(tag, index=0):    
    xmlData = dom.getElementsByTagName(tag)[index].firstChild.data
    return xmlData

data=sys.stdin.read()
dom = parseString(data)

ele2=get_tagged_data2('title')
print ele2

count=int(get_tagged_data2('fullcount'))
print count,"New Messages:"

for i in range(0,count):
    nam=get_tagged_data2('name',i)
    email=get_tagged_data2('email',i)
    print "  {0}: {1} <{2}>".format(i+1,nam,email)

现在将其保存在一个文本文件中,在其上运行chmod +x,然后:

curl -u $1:$2 --silent "https://mail.google.com/mail/feed/atom" | 
/path/pythonfile.py

它产生这个:

Gmail - Inbox for xxxxxxx@gmail.com
2 New Messages:
  1: bob smith <bob@smith.com>
  2: Google Alerts <googlealerts-noreply@google.com>

编辑 2 如果您不喜欢这样,这里是 Python 1 行过滤器:

curl -u $1:$2 --silent "https://mail.google.com/mail/feed/atom" |python -c ' 
import sys, re
for t,m in re.findall(r"<(title|name)>(.*)<\/\1>",sys.stdin.read()):
    print "\t",m
'

【讨论】:

  • 刚刚修复了 perl - 很多都没有显示...奇怪。我发现
     标签有困难
  • '
【解决方案2】:

您可以使用来自urllib2 标准 Python 模块的“URL 打开器”和处理程序进行身份验证。例如:

#!/usr/bin/env python

import getpass
import sys
import urllib2

def main(program, username=None, password=None, url=None):

    # Get input if any argument is missing
    username = username or raw_input('Username: ')
    password = password or getpass.getpass('Password: ')
    url = url or 'https://mail.google.com/mail/feed/atom'

    # Create password manager
    password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
    password_mgr.add_password(None, url, username, password)

    # Create HTTP Authentication handler and URL opener
    authhandler = urllib2.HTTPBasicAuthHandler(password_mgr)
    opener = urllib2.build_opener(authhandler)

    # Fetch URL and print content
    response = opener.open(url)
    print response.read()

if __name__ == '__main__':
    main(*sys.argv)

如果您也想从提要中提取信息,您应该检查如何解析 Password-Protected Feedsfeedparser

【讨论】:

    猜你喜欢
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多