2016-06-10 62 views
2

我正在写一个快速的Python脚本来对我们的一些Hibernate映射文件进行一些检查。我试图使用Python的这一点,以获得一个POJO的表名,它的类路径是否被完全定义:Python中的反斜杠正则表达式

searchObj = re.search(r'<class name="(.*\\.|)' + pojo + '".*table="(.*?)"', contents) 

但是 - 说POJO是“为MyObject” - 正则表达式不匹配它这一行:

<class name="com.place.package.MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true"> 

如果我打印字符串(而在PDB停止)我用搜索,我看到:

'<class name="(.*\\\\.|)MyObject".*table="(.*?)"' 

我很困惑,什么错这里。首先,我的印象是'r'前缀使得反斜杠不会被转义。即便如此,如果我删除了反斜杠的一个这样的,我的搜索字符串是这样的:

searchObj = re.search(r'<class name="(.*\.|)' + pojo + '".*table="(.*?)"', contents) 

和字符串搜索变得

'<class name="(.*\\.|)MyObject".*table="(.*?)"' 

它仍然没有返回匹配。这里有什么问题?我打算使用的regex表达式适用于regex101.com(在显然有问题的区域只有一个反斜杠)。任何想法在这里出了什么问题?

+0

@Keatinge - 为什么是不是匹配,那么,当我只有一个反斜杠?正则表达式应该基于该网站。另外 - 如果它只是MyObject,它匹配,但如果它是com.place.package.MyObject,它不会。 –

回答

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)) 
+0

是的,用管道结束它,做你说的功能同样的方法。至于你的评论的其余部分,在我发布的后半部分,我表明它也不值得用r'\'。不是,所以这不是我遇到的问题。 –

+0

@TrevorThackston:反斜线绝对是问题的一部分。我已经用一个工作示例更新了我的答案,表明该模式与完全限定名称和相对名称都匹配。 –

+0

你说得对 - 我只是说我说过我已经尝试过了。无论如何,我想出了它在真实数据集上遇到的问题。一些表格在表格后面有'mutable ='false'',所以它变得混乱并显示错误。想通了如何解决这个问题。 –

2

Pythex,我想这正则表达式:此字符串

<class name="(.*)\.MyObject" table="([^"]*)"

<class name="com.place.package.MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true">

,得到了这两个赛捕捉:

  1. com.place.package
  2. 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打印此文件,它将会跳出输出并向您显示"\\\\"
+0

问题在于正则表达式的第一部分,而不是第二部分,并且您更改了第一部分,使其仅适用于合格的路径名。 –

+0

@TrevorThackston我不知道'合格的路径名'是什么意思,所以请澄清。给我一些你希望第一部分匹配的东西的例子。 –

+0

我想它匹配这两个: '<类名=“com.place.package.MyObject”表=“my_cool_object”动态插入=“真”的动态更新=“真”>' 和 '' –