查找python代码文件中的所有字符串

时间:2009-02-25 10:44:03

标签: python

我想在我的大型python项目中列出所有字符串。

想象一下在python中创建字符串的不同可能性:

mystring = "hello world"

mystring = ("hello "
            "world")

mystring = "hello " \
           "world"

我需要一个工具,为我项目中的每个字符串输出“filename,linenumber,string”。使用“\”或“('')”分布在多行上的字符串应显示在一行中。

任何想法如何做到这一点?

6 个答案:

答案 0 :(得分:11)

展开在2.6中使用ast模块的建议是一个很好的建议。 (2.5中也有未记录的_ast模块。)这是

的示例代码
code = """a = 'blah'
b = '''multi
line
string'''
c = u"spam"
"""

import ast
root = ast.parse(code)

class ShowStrings(ast.NodeVisitor):
  def visit_Str(self, node):
    print "string at", node.lineno, node.col_offset, repr(node.s)

show_strings = ShowStrings()
show_strings.visit(root)

问题是多行字符串。如果你运行上述内容,你就会得到。

string at 1 4 'blah'
string at 4 -1 'multi\nline\nstring'
string at 5 4 u'spam'

您会看到它不报告多行字符串的开头,只报告结束字符串。使用内置的Python工具没有很好的解决方案。

另一个选择是您可以使用我的“python4ply”模块。这是PLY的Python的语法定义,它是一个解析器生成器。以下是您可以使用它的方法:

import compiler
import compiler.visitor

# from python4ply; requires the ply parser generator
import python_yacc

code = """a = 'blah'
b = '''multi
line
string'''
c = u"spam"
d = 1
"""

tree = python_yacc.parse(code, "<string>")
#print tree

class ShowStrings(compiler.visitor.ASTVisitor):
    def visitConst(self, node):
        if isinstance(node.value, basestring):
            print "string at", node.lineno, repr(node.value)

visitor = ShowStrings()
compiler.walk(tree, visitor)

此输出是

string at 1 'blah'
string at 2 'multi\nline\nstring'
string at 5 u'spam'

不支持列信息。 (有一些主要是完整的注释代码来支持它,但它没有经过全面测试。)然后,我再次看到你不需要它。它还意味着使用Python的'编译器'模块,它比AST模块更笨拙。

尽管如此,使用30-40行代码,你应该拥有你想要的代码。

答案 1 :(得分:7)

Python包含的tokenize模块也可以解决问题。

from __future__ import with_statement
import sys
import tokenize

for filename in sys.argv[1:]:
    with open(filename) as f:
        for toktype, tokstr, (lineno, _), _, _ in tokenize.generate_tokens(f.readline):
            if toktype == tokenize.STRING:
                strrepr = repr(eval(tokstr))
                print filename, lineno, strrepr

答案 2 :(得分:3)

如果您可以在Python中执行此操作,我建议首先查看ast(抽象语法树)模块,然后从那里开始。

答案 3 :(得分:2)

您是否在询问Python中的I18N实用程序?

http://docs.python.org/library/gettext.html#internationalizing-your-programs-and-modules

有一个名为po-utils(以前称为xpot)的实用程序可以帮助解决这个问题。

http://po-utils.progiciels-bpi.ca/README.html

答案 4 :(得分:2)

您也可以考虑使用解析代码 pygments.

我不知道其他解决方案,但确实非常 简单易用。

答案 5 :(得分:0)

Gettext可能会对您有所帮助。将您的字符串放在_( ... )结构中:

a = _('Test')
b = a
c = _('Another text')

然后在shell提示符下运行:

pygettext test.py

您将获得包含所需信息的messages.pot文件:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2009-02-25 08:48+BRT\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"


#: teste.py:1
msgid "Test"
msgstr ""

#: teste.py:3
msgid "Another text"
msgstr ""