我正在写一个快速的Python脚本来对我们的一些Hibernate映射文件进行一些检查。我试图使用这个Python来获取POJO的表名,无论其类路径是否已完全定义:
searchObj = re.search(r'<class name="(.*\\.|)' + pojo + '".*table="(.*?)"', contents)
然而 - 说pojo是&#39; MyObject&#39; - 正则表达式与此行不匹配:
<class name="com.place.package.MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true">
如果我打印字符串(在Pdb中停止)我正在搜索,我看到了:
'<class name="(.*\\\\.|)MyObject".*table="(.*?)"'
我很困惑这里出了什么问题。首先,我的印象是&#39; r&#39;前缀使得反斜杠不会被转义。即便如此,如果我删除其中一个反斜杠,使得我的搜索字符串为:
searchObj = re.search(r'<class name="(.*\.|)' + pojo + '".*table="(.*?)"', contents)
搜索的字符串变为
'<class name="(.*\\.|)MyObject".*table="(.*?)"'
它仍然没有返回匹配。这里出了什么问题?我打算使用的正则表达式在regex101.com上运行(在明显有问题的区域只有一个反斜杠。)任何想法在这里出了什么问题?
答案 0 :(得分:2)
在Pythex上,我尝试了这个正则表达式:
<class name="(.*)\.MyObject" table="([^"]*)"
在这个字符串上:
<class name="com.place.package.MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true">
并获得了这两个匹配捕获:
com.place.package
my_cool_object
所以我认为在你的情况下,这一行
searchObj = re.search(r'<class name="(.*)\.' + pojo + '"table="([^"]*)"', contents)
将产生您想要的结果。
关于令人困惑的反斜杠 - 在Python文档7.2. re
— Regular expression operations上添加两个然后四个显示,它解释了r''
是“原始字符串表示法”,用于规避Python的常规字符转义,使用反斜杠。所以:
'\\'
表示“由一个反斜杠组成的字符串”,因为字符串中的第一个反斜杠会转义第二个反斜杠。 Python看到了第一个反斜杠,并认为“下一个角色是一个特殊的角色”;然后它看到第二个并说,'特殊字符是一个实际的反斜杠'。它存储为单个字符\
。如果你要求Python打印它,它将转义输出并显示"\\"
。r'\\'
表示“由两个实际反斜杠组成的字符串。它存储为字符\
,后跟字符\
。如果你要求Python打印它,它将转义输出并显示"\\\\"
。答案 1 :(得分:2)
鉴于此:
re.search(r'<class name="(.*\\.|)' + pojo + '".*table="(.*?)"', contents)
模式的第一部分解释如下:
1. class name=" a literal string beginning with c and ending with "
2. ( the beginning of a group
3. .* zero or more of any characters
4. \\ a literal single slash
5. . any single character
6. OR
7. nothing
8. ) end of the group
由于您要搜索的字符串没有文字反斜杠,因此不匹配。
如果您希望\\.
表示“文字句号”,则需要一个反斜杠,因为它位于原始字符串中:\.
此外,用管道结束组似乎很奇怪。我不确定你认为那是在做什么。如果您的意思是说“任意数量的字符以点结尾,或者什么都没有”,您可以使用(.*\.)?
执行此操作,因为?
表示“零或前一个匹配”。
这似乎对我有用:
import re
contents1 = '''<class name="com.place.package.MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true">'''
contents2 = '''<class name="MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true">'''
pojo="MyObject"
pattern = r'<class name="(.*\.)?' + pojo + '.*table="(.*?)"'
assert(re.search(pattern, contents1))
assert(re.search(pattern, contents2))