我需要采用正则表达式模式并以编程方式转义花括号。输入正则表达式将匹配以下模式(标签之前,之后和之间的文本):
&{token1}
&{token1}&{token2}&{tokenN...}
&{token1&{token2&{tokenN...}}}
到目前为止,我对除嵌套标签之外的所有内容都很好。这就是我所拥有的。
regex = regex.replaceAll("(&)(\\{)([^{}]+)(\\})", "$1\\\\$2$3\\\\$4");
我也试过使用迭代和递归,但我遇到的问题是,一旦最内层的令牌被转义,它就会与匹配混乱。
我尝试过负面的看守,但这并不符合我的预期。它只会匹配/替换最里面的令牌。
regex = regex.replaceAll("(&)(\\{)([^(?<!\\\\{)|(?<!\\\\})]+)(\\})", "$1\\\\$2$3\\\\$4");
有什么建议吗?提前谢谢。
编辑:示例输入/输出
&{token1} //input
&\{token1\} //output
&{token1}&{token2}&{tokenN...} //input
&\{token1\}&\{token2\}&\{tokenN...\} //output
&{token1&{token2&{tokenN...}}} //input
&{token1&{token2&\{tokenN...\}}} //output
&\{token1&\{token2&\{tokenN...\}\}\} //expected output
//To throw a wrench into it, normal quantifiers should not be escaped
text{1,2}&{token1&{token2&{tokenN...}}} //input
text{1,2}&{token1&{token2&\{tokenN...\}}} //output
text{1,2}&\{token1&\{token2&\{tokenN...\}\}\} //expected output
编辑2:在此过程之外发生的事例的示例:标签将被解析为文本,然后最终,它应该是有效的正则表达式。
a{2}&{token1&{token2&{tokenN...}}} //input
a{2}&\{token1&\{token2&\{tokenN...\}\}\} //expected output of this regex
a{2}foobarbaz //expected output after tokens are resolved (&{token1} = foo, &{token2} = bar, &{tokenN...} = baz)
答案 0 :(得分:1)
尝试:
regex = regex.replaceAll("(?<=&)(?=\\{)|(?<!\\{\\d{0,6},?(\\d{0,6})?)(?=\\})","\\\\");
其中(0,6)
确定可以有多少位数,我认为6就足够了
Java示例:
public class Main {
public static void main(String[] args){
int i = 0;
String regex = "&{token1}&{token2}&{tokenN}\n" +
"&{token1&{token2&{tokenN}}}\n" +
"text{1,2}&{token1{1}&{token2{1,}&{tokenN{0,2}}}}\n";
regex = regex.replaceAll("(?<=&)(?=\\{)|(?<!\\{\\d{0,6},?(\\d{0,6})?)(?=\\})","\\\\");
System.out.println(regex);
}
}
带输出:
&\{token1\}&\{token2\}&\{tokenN\}
&\{token1&\{token2&\{tokenN\}\}\}
text{1,2}&\{token1{1}&\{token2{1,}&\{tokenN{0,2}\}\}\}
答案 1 :(得分:1)
我会避免正则表达式并创建简单的状态机,它将存储有关{
转义的决策序列。根据这些信息,每当我们找到}
时,我们就可以做出适当的决定来逃避或取消它并删除最后的信息,因为我们不再需要它了。
所以你的代码看起来像
public static String myEscape(String text){
StringBuilder sb = new StringBuilder();
char prev = '\0';
Stack<Boolean> stack = new Stack<>();
for (char ch : text.toCharArray()){
if (ch == '{'){
if (prev == '&'){
sb.append('\\');
}
stack.push(prev == '&');
}else if (ch == '}'){
if (stack.pop()){
sb.append('\\');
}
}
sb.append(ch);
prev = ch;
}
return sb.toString();
}
示例:
text{1,2}&{token1&{token2{foo}...}}
{
并看到它之前没有&
我们放在堆栈false
}
并基于堆栈的最高值(false)时,决定不应对其进行转义{
,因为它前面有&
,我们放在堆栈true
{
,因为它前面还有&
,我们将其放在堆栈顶部另一个true
{
这次没有&
,所以我们放在堆栈顶部false
因此,当我们看到堆栈存储信息有关我们是否应该转发}
时,false -> true -> true
当前}
我们可以看到下一个}
意味着我们应该期待\}
} \}
@Named(value = "filterBean")
@ViewScoped
public class FilterBean {
private List<Clientactions> filterDept;
public FilterBean() {
}
public List<Clientactions> getFilterDept() {
return filterDept;
}
public List<Clientactions> getFilterDept() {
return filterDept;
}
public void setFilterDept(List<Clientactions> filterDept) {
this.filterDept = filterDept;
}
// rest of bean code
。