如果嵌套,字符串替换所有regex模式以不匹配

时间:2021-07-26 21:43:39

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])[^\[\]]+\]

DEMO

演示

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])[^\[\]]+\]

DEMO

演示

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]]