2015-10-05 40 views
3

问题:为什么如下所述是代码切断了一些字段的最后一个字符?问题与反斜坡鼠疫和re.split

我有一个字符串,我需要解析,拆分,然后作为键/值导入字典。我的问题是一个字段可能包含多个嵌入逗号分隔的子字段,但在这些情况下,逗号前有三个反斜杠。我有代码99%的工作,但由于某种原因使用下面的代码(我认为应该工作)导致所有其他领域的最后一个字符被剥夺。我认为我理解Python Regex中的“反斜杠瘟疫”,我尝试了几种方法,但是找不到既不会分裂“ConfigChangeData”也不会放弃其他字段的最后一个字符的方法。

首先,这里是我开始的字符串(在一个变量称为数据):

2015-10-05 18:08:47,186 root   INFO  <181>Oct 5 17:09:10 someservername Administrative_and_Operational_Audit 0000419602 1 0 2015-10-05 17:09:10.841 -05:00 0000006065 52001 NOTICE Configuration-Changes: Changed configuration, Version=someversion.x86_64, ConfigVersionId=150, AdminInterface=GUI, AdminIPAddress=192.168.1.77, AdminSession=46CE916D0502A641592B105FF7CB3B70, AdminName=admin, ConfigChangeData='RADIUS:Shared Secret'='********'\\\,'TACACS+:Shared Secret'='********'\\\,'IP Address'='127.0.0.91/32', ObjectType=Network Device, ObjectName=testclient, ObjectId=4072, inLocalMode=false, 

这里是我的代码:

##split the syslog data into CSV's in a list 
#Here be dragons: One field, "ConfigChangeData" can have multiple embedded 
#subfields. This is indicated by three trailing backslashes 
#The following line needs to split on commas NOT proceeded by a backslash 
csvlist=re.split("[^\\\\],", data) 
AVPdict=dict() 
##Create an Attribute/value pair by analysing the CSV values 
##If the CSV value represents a AVP pair (detected by presense of an = sign) 
##add it to the AVP dict 
for csv in csvlist: 
    logger.debug("csv: %s" %(csv)) 
    if re.search("=", csv): 
     csv=csv.strip() # clear out some embedded whitespace 
     attribute,value=csv.split("=", 1) 
     AVPdict[attribute]=value 

下面是从日志输出:

2015-10-05 18:08:47,189 root   DEBUG csv: Version=someversion.x86_6 
2015-10-05 18:08:47,190 root   DEBUG csv: ConfigVersionId=15 
2015-10-05 18:08:47,190 root   DEBUG csv: AdminInterface=GU 
2015-10-05 18:08:47,190 root   DEBUG csv: AdminIPAddress=192.168.7 
2015-10-05 18:08:47,191 root   DEBUG csv: AdminSession=46CE916D0502A641592B105FF7CB3B7 
2015-10-05 18:08:47,191 root   DEBUG csv: AdminName=admi 
2015-10-05 18:08:47,191 root   DEBUG csv: ConfigChangeData='RADIUS:Shared Secret'='********'\\\,'TACACS+:Shared Secret'='********'\\\,'IP Address'='127.0.0.91/32 
2015-10-05 18:08:47,192 root   DEBUG csv: ObjectType=Network Devic 
2015-10-05 18:08:47,192 root   DEBUG csv: ObjectName=testclien 
2015-10-05 18:08:47,192 root   DEBUG csv: ObjectId=407 
2015-10-05 18:08:47,193 root   DEBUG csv: inLocalMode=fals 
2015-10-05 18:08:47,193 root   DEBUG csv: 
+0

'“\\\\”包括'是与'r'\''相同。我不确定你的3个反斜杠在哪里。 –

+0

这三个反斜杠是在匹配的字符串中:ConfigChangeData ='RADIUS:Shared Secret'='********'\\\,'TACACS +:Shared Secret'='******* *'\\\,'IP Address'='127.0.0.91/32': – wvunathans

回答

2

你的正则表达式模式正在消耗逗号之前的最后一个字符,因为这个字符是你模式的一部分,重新分裂。它是由丑陋的[^\\\\]位模式匹配的字符。

我认为你想要一个负面后顾之忧。这可以让你检查前面的字母是不是反斜杠,而不是实际在匹配中包含该字符。

csvlist=re.split(r"(?<!\\),", data) 

请注意,我使用的是原始字符串,所以你只需要两个反斜杠,而不是你最初使用四个。

+0

D'oh。我非常关注“当反斜杠匹配”条件时,我忘记了“当反斜杠不匹配”时。我尝试了原始字符串,但无法启动它,为什么现在很明显。就像老引用一样:有些人遇到问题时,会想:“我知道,我会用正则表达式。”现在他们有两个问题。 – wvunathans

+0

在“两个问题”方面,如果您传递'escapechar'关键字变量,则Python的'csv'模块可以处理逗号分隔的字符串,因此如果您有多行数据(而不仅仅是一行),则可能值得尝试而不是're'。 – Blckknght

+0

@Blckknght我打算建议使用[**'csv' **](https://docs.python.org/2/library/csv.html),但[**'escapechar' **] (https://docs.python.org/2/library/csv.html#csv.Dialect.escapechar)只是一个字符。 –

0

您需要为您re.split模式的回顾后,这样的逗号之前的字符不是定界符(即拆分字符)

re.split(r"(?<=[^\\]),",data)