2010-06-15 95 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 

你怎麼知道的?你決定這個的基礎是什麼?

相關問題