解析Python:抑制/规范化字符串的最有效方法是什么?

时间:2009-05-11 05:55:04

标签: python string parsing

我正在解析源文件,我想“抑制”字符串。我的意思是将每个像“bla bla bla + / *”这样的字符串转换为类似“字符串”的字符串,这些字符串是确定性的,并且不包含任何可能使我的解析器混淆的字符,因为我不关心它的价值字符串。这里的问题之一是使用例如字符串格式化。 “%s”,请看下面我对此的评论。

以下面的伪代码为例,它可能是我正在解析的文件的内容。假设字符串以“开头”,并且“转出”字符由“”:

完成
print(i)
print("hello**")
print("hel"+"lo**")
print("h e l l o "+
"hello\n")
print("hell""o")
print(str(123)+"h e l l o")
print(uppercase("h e l l o")+"g o o d b y e")

应转换为以下结果:

print(i)
print("string")
print("string"+"string")
print("string"
"string")
print("string")
print(str(123)+"string")
print(uppercase("string")+"string")

目前我把它视为代码中的特殊情况(即检测字符串的开头,并且“手动”运行直到结束时有几个子特殊情况)。如果有一个Python库函数我可以使用或一个很好的正则表达式可以使我的代码更有效,那将是伟大的。

几点评论:

  • 我希望“start-of-string”字符是一个变量,例如'vs“。
  • 我现在没有在解析Python代码,但我打算在那里,问题显然变得更加复杂,因为字符串可以以多种方式启动,并且必须以与开始相对应的方式结束。我现在并没有试图解决这个问题,但如果有任何完善的最佳实践,我想了解它。
  • 关于这种“抑制”最让我烦恼的事情是使用'%s'之类的字符串格式化,这是有意义的令牌。我目前没有处理这个问题,并没有完全考虑过,但如果你们有任何关于如何处理这个问题的建议会很好。请注意我对字符串标记的特定类型或格式不感兴趣,这足以让我知道字符串中有标记(多少个)。备注这里可能很重要:我的tokenizer没有嵌套,因为我的目标非常简单(我没有编译任何东西......)。
  • 我不太清楚start-string字符的转义。您会说在大多数编程语言中实现它的常用方法是什么?假设是双重发生(例如“”)还是任何一组两个字符(例如'\“')足以逃脱?我是否需要处理其他情况(想想Java,C / C ++,PHP,C等语言) )?

3 个答案:

答案 0 :(得分:4)

选项1:要清理Python源代码,请尝试使用内置的tokenize模块。它可以在任何Python源文件中正确查找字符串和其他标记。

选项3:将pygments与HTML输出一起使用,并用"string"替换蓝色(等)中的任何内容。 pygments支持几十种语言。

选项2:对于大多数语言,您可以构建自定义正则表达式替换。例如,以下内容清理Python源代码(但如果源文件包含"""''',则不起作用):

import re
sanitized = re.sub(r'(#.*)|\'(?:[^\'\\]+|\\.)*\'|"(?:[^"\\]+|\\.)*"',
    lambda match: match.group(1) or '"string"', source_code)

即使字符串包含反斜杠(\"\\\n\\\\"\\\",上面的正则表达式也能正常工作所有工作都很好。)

在构建正则表达式时,请确保匹配注释(因此regexp替换不会触及注释中的字符串)和正则表达式文字(例如Perl,Ruby和JavaScript),并注意匹配反斜杠和换行符正确(例如在Perl和Ruby中,字符串可以包含换行符)。

答案 1 :(得分:1)

您没有提到使用lexerparser采取行动。如果事实上你没有,请看看例如tokenize模块(可能是您想要的)或第三方模块PLY(Python Lex-Yacc)。您的问题需要系统的方法,而这些工具(和其他工具)提供它。

(请注意,一旦您对代码进行了标记化,您就可以将另一个专用标记生成器应用于字符串的内容,以检测特殊格式指令,例如%s。在这种情况下,定期但是,表达可能会起作用。)

答案 2 :(得分:1)

为每种语言使用专用解析器 - 特别是因为人们已经为您完成了这项工作。你提到的大多数语言都有语法。