2017-07-06 146 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