簡體   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