consider the scenario below i have an input string
考虑下面的场景,我有一个输入字符串
"input [yes] [yes] [yes] [mk:[yes] [yes] [yes]] [yes] [iif:[yes] [yes] [yes]]"
my desired out string after replace all is all [yes]
will be replaced with Yes
however if it is nested within a secondary or n-backets such patterns should be ignored, the assumption here is that all opening brackets will be properly closed, here is the desired output string
我想要的out字符串替换为all [yes]后将被替换为yes,但是如果它嵌套在辅助或n-backets中,这些模式应该被忽略,这里的假设是所有的开始括号将被正确关闭,这是期望的输出字符串
"input Yes Yes Yes [mk:[yes] [yes] [yes]] Yes [iif:[yes] [yes] [yes]]"
here is my question in a nutshell, can regex understand 'nested' patterns? or is recursion an absolute necessity in doing accomplishing this and regex is simply not sufficient enough
简单地说,我的问题是,regex能理解“嵌套”模式吗?或者,递归是完成这个任务的绝对必要条件,而regex是不够充分的。
if detecting infinitely nested regex cannot be done, how about nested to the second degree only like my examples
如果检测到无限嵌套的regex无法完成,那么嵌套到第二个级别的情况就像我的例子一样。
2 个解决方案
#1
2
EDIT 1
编辑1
As this cannot be done with regex as pointed out by vks, I wrote a simple program that'll do the same for you in Java:
正如vks指出的那样,这不能通过regex来实现,因此我编写了一个简单的程序,它将在Java中为您实现同样的功能:
public class Main {
public static String nestedReplace(String s) {
int nested =0,i=0;
StringBuilder o = new StringBuilder();
while(i<s.length())
{
if(nested==0 && s.regionMatches(i,"[yes]",0,4))
{
o.append("Yes");
i += 5;
continue;
}
else if(s.charAt(i) == '[')
nested++;
else if(s.charAt(i) == ']')
nested--;
o.append(s.charAt(i));
i++;
}
return new String(o);
}
public static void main(String[] args) {
System.out.println(nestedReplace("input [yes] [yes] [yes] [mk:[yes] [yes] [yes]] [yes] [iif:[yes] [yes] [yes]]"));
}
}
Output:
输出:
input Yes Yes Yes [mk:[yes] [yes] [yes]] Yes [iif:[yes] [yes] [yes]]
#2
1
Try with:
试一试:
\[[^\[\]]+\[.+?][^\[\]]*\]|\[([a-z])[^\[\]]+\]
演示
With this you will match the whole nested brackets, or not-nested bracket. Then replace content only if Matcher
will find group(1)
(not nested bracket), like in:
使用此方法,您将匹配整个嵌套括号或非嵌套括号。然后仅当Matcher发现group(1)(非嵌套括号)时才替换内容,如:
public class Test {
public static void main(String[] args){
String[] strings = {"input [yes] [yes] [yes] [mk:[yes] [yes] [yes]] [yes] [iif:[yes] [yes] [yes]]",
"input [yes] [yes] [yes[yes] [yes] [yes] [mk:[yes] [yes] [yes]] [yes] [mk:[yes] [yes] [yes]] [yes] [iif:[yes] [yes] [yes]]",
"input [yes] [yes] [yes[yes] [yes] [yes] [mk:[yes] [yes] [yes]] [mk:[yes] [yes] [yes]] [yes] [iif:[yes] [yes] [yes]]"};
Pattern pattern = Pattern.compile("\\[[^\\[\\]]+\\[.+?][^\\[\\]]*\\]|\\[([a-z])[^\\[\\]]+\\]");
for(String string : strings) {
Matcher matcher = pattern.matcher(string);
while (true) {
if (matcher.find()) {
if (matcher.group(1) != null) {
string = string.substring(0, matcher.start(1)) + string.substring(matcher.start(1), matcher.end(1)).toUpperCase() + string.substring(matcher.end(1));
matcher.reset(string);
}
} else {
break;
}
}
System.out.println(string);
}
}
}
which gives output:
这使输出:
input [Yes] [Yes] [Yes] [mk:[yes] [yes] [yes]] [Yes] [iif:[yes] [yes] [yes]]
input [Yes] [Yes] [yes[yes] [yes] [yes] [mk:[yes] [yes] [yes]] [Yes] [mk:[yes] [yes] [yes]] [Yes] [iif:[yes] [yes] [yes]]
input [Yes] [Yes] [yes[yes] [yes] [yes] [mk:[yes] [yes] [yes]] [mk:[yes] [yes] [yes]] [Yes] [iif:[yes] [yes] [yes]]
#1
2
EDIT 1
编辑1
As this cannot be done with regex as pointed out by vks, I wrote a simple program that'll do the same for you in Java:
正如vks指出的那样,这不能通过regex来实现,因此我编写了一个简单的程序,它将在Java中为您实现同样的功能:
public class Main {
public static String nestedReplace(String s) {
int nested =0,i=0;
StringBuilder o = new StringBuilder();
while(i<s.length())
{
if(nested==0 && s.regionMatches(i,"[yes]",0,4))
{
o.append("Yes");
i += 5;
continue;
}
else if(s.charAt(i) == '[')
nested++;
else if(s.charAt(i) == ']')
nested--;
o.append(s.charAt(i));
i++;
}
return new String(o);
}
public static void main(String[] args) {
System.out.println(nestedReplace("input [yes] [yes] [yes] [mk:[yes] [yes] [yes]] [yes] [iif:[yes] [yes] [yes]]"));
}
}
Output:
输出:
input Yes Yes Yes [mk:[yes] [yes] [yes]] Yes [iif:[yes] [yes] [yes]]
#2
1
Try with:
试一试:
\[[^\[\]]+\[.+?][^\[\]]*\]|\[([a-z])[^\[\]]+\]
演示
With this you will match the whole nested brackets, or not-nested bracket. Then replace content only if Matcher
will find group(1)
(not nested bracket), like in:
使用此方法,您将匹配整个嵌套括号或非嵌套括号。然后仅当Matcher发现group(1)(非嵌套括号)时才替换内容,如:
public class Test {
public static void main(String[] args){
String[] strings = {"input [yes] [yes] [yes] [mk:[yes] [yes] [yes]] [yes] [iif:[yes] [yes] [yes]]",
"input [yes] [yes] [yes[yes] [yes] [yes] [mk:[yes] [yes] [yes]] [yes] [mk:[yes] [yes] [yes]] [yes] [iif:[yes] [yes] [yes]]",
"input [yes] [yes] [yes[yes] [yes] [yes] [mk:[yes] [yes] [yes]] [mk:[yes] [yes] [yes]] [yes] [iif:[yes] [yes] [yes]]"};
Pattern pattern = Pattern.compile("\\[[^\\[\\]]+\\[.+?][^\\[\\]]*\\]|\\[([a-z])[^\\[\\]]+\\]");
for(String string : strings) {
Matcher matcher = pattern.matcher(string);
while (true) {
if (matcher.find()) {
if (matcher.group(1) != null) {
string = string.substring(0, matcher.start(1)) + string.substring(matcher.start(1), matcher.end(1)).toUpperCase() + string.substring(matcher.end(1));
matcher.reset(string);
}
} else {
break;
}
}
System.out.println(string);
}
}
}
which gives output:
这使输出:
input [Yes] [Yes] [Yes] [mk:[yes] [yes] [yes]] [Yes] [iif:[yes] [yes] [yes]]
input [Yes] [Yes] [yes[yes] [yes] [yes] [mk:[yes] [yes] [yes]] [Yes] [mk:[yes] [yes] [yes]] [Yes] [iif:[yes] [yes] [yes]]
input [Yes] [Yes] [yes[yes] [yes] [yes] [mk:[yes] [yes] [yes]] [mk:[yes] [yes] [yes]] [Yes] [iif:[yes] [yes] [yes]]