2017-07-06 144 views
1

用戶輸入格式:模式匹配 - 正則表達式

[fieldname1]比較[fieldvalue1,fieldvalue2,值3],[fieldname2] 比較[fieldvalue1,值2,..],..

需要解析成這樣:

1 fieldname1]比較[fieldvalue1,fieldva lue2,值3]

2 fieldname2]比較[fieldvalue1,值2,..]等

(IE)的每個字段與它的比較器和值一起必須被分離。 而比較器將是以下中的任何一個:

< = |> = | = | is | < |> |首頁|以|開始|開始|開始|結束 與| Endswith |

包含由我使用

正則表達式:

([?()+](\ S)(< = |> = | = |是| < | > | startswith |啓動 與| Beginswith |與起始|完 與|的endsWith |包含)(\ S) [()+。?](\)*)

示例: [公司]包含[abc,efg],[email]包含[cdf,測試] 正確解析沒有問題。

問題: 當字段名稱或字段值包含符號「[」或「]」時解析出錯。

例如: [公司]包含[AB [] C,EFG],[郵件]包含[溼婆,測試]

以上是有效的,但因爲[]作爲分隔符停止解析,直到[公司]包含[AB [],但我希望它正確地解析如上例如,

1. [公司]包含[AB [] C,EFG]

2. [電子郵件]包含[溼婆,測試]

謝謝。

+1

你使用什麼語言/工具?我不確定你可以使用純正則表達式得到你想要的編號。 –

+0

語言是JAVA – Naksh17

回答

0

你可以用這個表達式嘗試:

,(?=(?:(?:[^\\[\\]]*[\\]\\[]){2})*[^\\[\\]]*$) 

分割你的目標字符串應該給你一個分裂的結果集的列表。您可以在其中輕鬆應用比較器匹配

final String regex = ",(?=(?:(?:[^\\[\\]]*[\\]\\[]){2})*[^\\[\\]]*$)"; 
final String string = "[company] contains [ab[]c,efg],[email] contains [siva,test]"; 
String[] res=string.split(regex); 
System.out.println(Arrays.asList(res).toString()); 

通過使用此功能,您可以得到exptected結果。您可能需要檢查的是,如果每個索引都包含正確的比較器,如您所示。如果沒有,那麼從數組中刪除它。

上面的代碼輸出:

[ 
    [company] contains [ab[]c,efg], 
    [email] contains [siva,test] 
] 

Regex101Demo

說明:

每當一個,被發現 - >

,(?=(?:(?:[^\\[\\]]*[\\]\\[]){2})*[^\\[\\]]*$) 

的p ositive向前看運行,直到字符串的末尾,其中以下行

(?:[^\\[\\]]*[\\]\\[]){2})*確保 - 如果找到括號,則會找到兩次。然後最後的*表示0或更多的括號對重複。

爲什麼這很重要?從任何逗號開始,然後統計[和]括號的數量。而且,如果後面只有偶數的括號,你會發現只需要用逗號分割即可。而且你不想爲之後的奇數支架分割逗號。這是解釋。

對於正則表達式的完整分解,您可以查看右上角部分中逐字符給出完整解釋的鏈接。

+0

謝謝! 可以請你解釋你提到的正則表達式。 **現有代碼**: 'Pattern p = Pattern.compile(criteriaRegex,Pattern.CASE_INSENSITIVE); \t \t \t \t int crtCount = 0; \t \t \t \t Matcher m = p.matcher(criteria); \t \t \t \t String [] criteriaArr = new String [100]; \t \t \t \t int start = 0,end = 0; \t \t \t \t \t \t \t \t而(m.find()){\t \t \t \t \t \t \t開始= m.start(0); \t \t \t \t \t end = m.end(0); \t \t \t \t \t String temp = criteria.substring(start,end); \t \t \t \t \t criteriaArr [crtCount] = temp; \t \t \t \t \t crtCount ++;' ** **感謝 – Naksh17

+0

@Siva我增加了一些解釋。 –

+0

非常感謝。它工作得很好!和餘施加\t \t \t \t \t'字符串nameValRegex =「(Ⅰ')(<=|> = | = |是| <|> | startswith |以| Beginswith |與起始|結束與|的endsWith |包含)?(=(?: (?:[^ \\ [\\]] * [\\] \\ []){2})* [^ \\ [\\]] * $)「;' 此正則表達式用於分隔比較器,名稱和價值。如果有更好的方法,請建議。 *謝謝Rizwan *! – Naksh17

0

所以基本上你需要分割字符串在,之間的][之間。

如果你使用谷歌的番石榴,您可以使用Splitter和分裂與positve lookbefore ]和積極的回顧後發正則表達式[

String s = "[fieldname1] comparator [fieldvalue1,fieldvalue2,value3],[fieldname2] comparator [fieldvalue1,value2]"; 
Pattern stringPattern = Pattern.compile("(?<=\\]),(?=\\[)"); 
Iterable<String> split = Splitter.on(stringPattern).omitEmptyStrings().split(s); 
split.forEach(System.out::println); 
0

首先,我們必須定義名稱匹配的正則表達式,另外一個,

private static final String NAME_RE = "[A-Za-z0-9_]+"; 
private static final String VALUE_RE = "[A-Za-z0-9_\\[\\]\\.]+"; 
private static final String COMPARATOR_RE 
     = "<=|>=|=|is|<|>|startswith|Starts with|Beginswith|Begins with|Ends with|Endswith|Contains"; 

現在,我們可以創建模式,結合這些子正則表達式:

比較,而第三個是相匹配的值相匹配
private static final String RE = "\\s*\\[(" + NAME_RE + ")\\]\\s*" 
     + "(" + COMPARATOR_RE + ")\\s*\\[\\s*(" 
     + VALUE_RE + "(?:\\s*,\\s*" + VALUE_RE + ")*)\\s*\\]" 
     + "(?:\\s*,\\s*(.*))?"; 
private static final Pattern PATTERN 
     = Pattern.compile(RE, Pattern.CASE_INSENSITIVE); 

請注意,它匹配的可能是也可能不是後跟逗號和其他規則的單個規則。

源字符串的解析必須重複的規則:

private static void parse(String source) { 
    String s = source; 
    while (s != null) { 
     Matcher matcher = PATTERN.matcher(s); 
     if (!matcher.matches()) { 
      throw new IllegalArgumentException("Invalid syntax: " + source); 
     } 
     String name = matcher.group(1); 
     String comparator = matcher.group(2); 
     String values = matcher.group(3); 
     s = matcher.group(4); 
     System.out.println("[" + name + "] " + comparator + " [" + values + "]"); 
    } 
} 

現在,讓我們嘗試分析你的兩個例子:

private static final String EXAMPLE1 = "[company] contains [abc,efg],[email] contains [cdf,test]"; 
private static final String EXAMPLE2 = "[company] contains [ab[]c,efg],[email] contains [siva,test]"; 

public static void main(String[] args) { 
    parse(EXAMPLE1); 
    parse(EXAMPLE2); 
} 

它產生以下輸出:

[company] contains [abc,efg] 
[email] contains [cdf,test] 
[company] contains [ab[]c,efg] 
[email] contains [siva,test] 

更新:

請注意,必須限制值的內容,因爲如果「efg」和「[email]包含[cdf」都是可接受的值,那麼無法知道這些示例是由一個還是兩個規則組成的。

更新2:

這裏是VALUE_RE一個相當寬鬆的正則表達式:

private static final String VALUE_RE 
     = "[^,\\[\\]]*(?:\\[[^,\\[\\]]*\\][^,\\[\\]]*)*"; 

這裏的值不能包含任何逗號,只有平衡支架,不包括嵌套。

+0

但是,當我試圖添加其他字符的字段名稱,它導致一些錯誤'私人靜態最終字符串NAME_RE =「[A-ZA-Z0-9 _,\\ [\\] \\ s〜 '!@#$%^&* \\(\\) - \\ +'\「\\。,\\/\\\\\\?? = = +」; ' 'private static final String EXAMPLE2 =「[LastName] = [test],[FullName] = [te],[Exchange Rate]是[1],[Decimal 1] = [12],[Companynumber] <= [123457]」; **感謝Maurice ** – Naksh17