2010-06-15 54 views
0

我的正则表达式的技巧不是很好,最近一个新的数据元素已抛出我的解析器成一个圈解析复杂的字符串使用正则表达式

采取以下字符串

“+ USER =鲍勃·史密斯-GROUP =管理员+功能=读/功能=写”

以前我有我的正则表达式如下:[+ \\ - /]

这将结果转换为

USER =鲍勃·史密斯
GROUP =管理员
功能=阅读
功能=写
功能=阅读

但现在我必须在他们破折号这是造成不好的输出

新的字符串看起来像“价值+ USER =鲍勃·史密斯-GROUP =管理+功能=读/功能=写/功能=读写”

这给了我下面的结果,并打破了key = value的结构。

USER =鲍勃·史密斯
GROUP =管理员
功能=阅读
功能=写
功能=阅读

有人可以帮我制定一个有效的正则表达式处理这个或点我一些关键/价值的例子。基本上我需要能够处理+ - /符号才能获得组合。

+1

当你的数据值可以包含你的分隔符时,正则表达式会大大地使情况复杂化。你对数据是如何控制的? – 2010-06-15 17:13:23

+0

不幸的是,这些数据来自我无法控制的许多不同来源。 – 2010-06-15 17:15:16

+0

可能更容易找到你正在寻找的密钥,而不是分离器?寻找'用户','组'和'功能'并解析相应的结果? – AllenG 2010-06-15 17:18:48

回答

0

你没有指定你正在使用的是什么正则表达式引擎,但是如果你有前瞻/后顾之处,这个工程就可以工作。

它的工作原理是键只有全部大写,而值不是 - 不知道这是否是一个有效的假设,但如果它不是那么如指出的事情会变得复杂和混乱。

(?<=[+-\/])[A-Z]+=(?:(?![A-Z]+=)[^=])+(?=[+-\/]|$) 


这里是我试图解释(不知道有多少这是有道理的):

(?x)   # enable regex comment mode 
(?<=[+-\/]) # start with one of the delimiters, but excluded from match 
[A-Z]+  # match one or more uppercase (for the key) 
=   # match the equal sign 

(?:   # start non-capturing group 

    (?!   # start negative lookahead, to prevent keys matching 
    [A-Z]+=  # a key and equals (since in negative lookahead, this is what we exclude) 
)   # end the negative lookahead 
    [^=]   # match a character that's not = 

)+   # end non-capturing group, match one or more times, until... 

(?=[+-\/]|$) # next char must be delimiter or end of line for match to succeed 


对于Java与字符串>正则表达式,反斜杠需要转义(如果有的话):

Pattern p = Pattern.compile("(?<=[+-\\/])[A-Z]+=(?:(?![A-Z]+=)[^=])+(?=[+-\\/]|$)"); 


如果需要捕获组,只需加括号一轮的适当部位:

Pattern p = Pattern.compile("(?<=[+-\\/])([A-Z]+)=((?:(?![A-Z]+=)[^=])+(?=[+-\\/]|$))"); 


的这一匹配的部分,把它变成新行分隔符的文本,就像...

Matcher m = p.Matcher(InputText); 
StringBuffer Result = new StringBuffer(""); 

while (m.find()) 
{ 
    Result.append(m.Group() + "\n"); 
} 
+0

对不起,我使用Java模式来执行正则表达式 模式p = Pattern.compile(“[+ \\ -//”“); 这些值可以是大写或小写,我没有问题翻转他们是一种情况。 – 2010-06-15 17:26:52

+0

那么,如果你能强迫关键和价值永远是不同的情况下,这可以让你区分,这意味着它可能是可能的。要在Java中使用上述表达式,只需双重转义所有'\'。 – 2010-06-15 17:37:51

+0

hhmm不幸的是我无法得到这个工作,它似乎在我的正则表达式测试中工作,但在Java代码中,结果很简单。不知道在需要的地方是否有正确的转义 – 2010-06-15 17:51:03

0

基于第二个示例中,该正则表达式:(\w+)=([\w|-|\s]+)返回这些结果:

USER=Bob Smith 
GROUP=Admin 
FUNCTION=Read 
FUNCTION=Write 
FUNCTION=Read-Write 

的括号提供每个元素分组,所以每个匹配将包含两个组,第一组的=之前将有一部分(这样的用户,组FUNCTION),第二个将具有值(鲍勃·史密斯,管理,读,写,读,写)

您也可以命名组是否会更容易:

(?<funcrion>\w+)=(?<value>[\w|-|\s]+) 

或者,如果你不关心这个群体,你可以删除这个parens altoge疗法

\w+=[\w|-|\s]+ 
+0

那里的命名组的东西不会工作,它只是.NET语法。 – 2010-06-15 17:34:31

+2

哦,这个正则表达式是错误的 - 你不能在字符类中使用交替 - 你想要或者((?:\ w | - | \ s)+)'或'([\ w \ - \ s] +)' - 除了错误地将GROUP键添加到USER值。 – 2010-06-15 17:36:06

+0

这似乎给我的价值观的消极影响,我怎么可以翻转这个获得键=值组合,而不是只是=或 - 的迹象? – 2010-06-15 17:46:18

0

另一种选择,如果你有一组有限的按键,你可以只匹配:


这在Java中我可能会实现这样的:

String Key = "USER|GROUP|FUNCTION" ; 
String Delim = "[+-\\/]"; 
Pattern p = Pattern.compile("(?<="+Delim+")("+Key+")=[^=]+(?=$|"+Delim+"(?:"+Key+"))"); 

这依赖于,例如“写”不是一个有效的关键(如果你可以强制吨他的键的情况是“写”或“写”,那么这意味着它会工作)。


的这一匹配的部分,把它变成新行分隔符的文本,是一样的东西......

Matcher m = p.Matcher(InputText); 
StringBuffer Result = new StringBuffer(""); 

while (m.find()) 
{ 
    Result.append(m.Group() + "\n"); 
} 
0

如果你用划界字符的字段,可以出现在值,你完蛋了。

假设你收到一个字符串,如:

one=a-two=b-three=c-d-four=e 

应该是解析到这一点?

one=a 
two=b 
three=c-d 
four=e 

还是应该分析一下呢?

one=a 
two=b 
three=c 
d-four=e 

你怎么知道的?你决定这个的基础是什么?

相关问题