繁体   English   中英

使用正则表达式解析复杂的字符串

[英]Parsing complex string using regex

我的正则表达式技能不是很好,最近有一个新的数据元素使我的解析器陷入循环

取以下字符串

“ + USER =鲍勃·史密斯-GROUP = Admin + FUNCTION =读/功能=写”

以前,我的正则表达式具有以下特征:[+ \\\\-//]

这将结果变成

USER =鲍勃·史密斯
GROUP =管理员
FUNCTION =读取
FUNCTION =写入
FUNCTION =读取

但是现在我的值中带有破折号,这会导致输出错误

新字符串如下所示:“ + USER = Bob Smith-GROUP = Admin + FUNCTION = Read / FUNCTION = Write / FUNCTION = Read-Write”

这给了我以下结果,并打破了键=值结构。

USER =鲍勃·史密斯
GROUP =管理员
FUNCTION =读取
FUNCTION =写入
FUNCTION =读取

有人可以帮我制定一个有效的正则表达式来处理此问题,还是可以给我指出一些关键/值示例。 基本上,我需要能够处理+-/符号才能获得组合。

您没有指定要使用的正则表达式引擎,但是如果您先行/后行,则可以使用此功能。

它的前提是键都是大写的,而键值不是大的-不确定这是否是一个有效的假设,但是如果不是这样,则会使事情变得复杂和混乱。

(?<=[+-\/])[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 string-> regex,反斜杠需要转义(如果有引号,也要转引):

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" );
}

根据您的第二个示例,此正则表达式: (\\w+)=([\\w|-|\\s]+)返回以下结果:

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

括号为每个元素提供了分组,因此每个匹配项将包含两个组,第一个将具有=之前的部分(因此USER,GROUP,FUNCTION),第二个将具有值(Bob Smith,Admin,Read,Write,读写)

您也可以命名组,如果这样可以更容易:

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

或者,如果您不在乎这些组,则可以完全删除括号

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

另一个选择是,如果您的键集有限,则可以匹配:

(?<=[+-\\/])(USER|GROUP|FUNCTION)=[^=]+(?=$|[+-\\/](?:USER|GROUP|FUNCTION))


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

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

这依赖于例如“ Write”不是有效的密钥(并且如果您可以强制将密钥的大小写为“ write”或“ WRITE”,那么这将起作用)。


匹配的部分将其变成换行符分隔的文本,类似于...

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

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

如果您用可能出现在值中的字符来分隔字段,则很麻烦。

假设您收到类似以下的字符串:

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

你怎么知道的? 您决定这个的依据是什么?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM