Nested regular expressions and replacement

I have type strings <p0=v0 p1=v1 p2=v2 ....>, and I want to swap pXto vX, to have something like <v0=p0 v1=p1 v2=p2 ....>, using regexps . I want only couples to <>switch places.

I wrote:

Pattern pattern = Pattern.compile("<(\\w*)=(\\w*)>");
Matcher matcher = pattern.matcher("<p1=v1>");
System.out.println(matcher.replaceAll("$2=$1"));

But it only works with one pair. pX=vX Can someone explain to me how to write regexp, which works for several pairs?

+3
source share
5 answers

You can use this template:

"((?:<|\\G(?<!\\A))\\s*)(p[0-9]+)(\\s*=\\s*)(v[0-9]+)"

To make sure that the pairs are after the bracket of the opening angle, the template starts with:

(?:<|\\G(?<!\\A))

this means: the bracket of the opening angle OR at the end of the last match

\\G ( , , ). , lookbehind (?<!\\A), .

<.

:

String subject = "p5=v5 <p0=v0 p1=v1 p2=v2 p3=v3> p4=v4";
String pattern = "((?:<|\\G(?<!\\A))\\s*)(p[0-9]+)(\\s*=\\s*)(v[0-9]+)";
String result = subject.replaceAll(pattern, "$1$4$3$2");

p v, , :

String pattern = "((?:<|\\G(?<!\\A))\\s*)(p([0-9]+))(\\s*=\\s*)(v\\3)";
String result = subject.replaceAll(pattern, "$1$5$4$2");

( ):

String pattern = "((?:<|\\G(?<!\\A))(?:[^\s>]+\\s*)*?\\s*)(p([0-9]+))(\\s*=\\s*)(v\\3)";
String result = subject.replaceAll(pattern, "$1$4$3$2");

. , . , , .

, (?=[^<>]*>) . , . (?<=<)[^<>]++(?=>) . , .

0

, :

String input = "<p0=v0 p1=v1 p2=v2>";
//                                   |group 1
//                                   ||matches "p" followed by one digit
//                                   ||      |... followed by "="
//                                   ||      ||group 2
//                                   ||      |||... followed by "v", followed by one digit
//                                   ||      |||          |replaces group 2 with group 1,
//                                   ||      |||          |re-writes "=" in the middle
System.out.println(input.replaceAll("(p[0-9])=(v[0-9])", "$2=$1"));

:

<v0=p0 v1=p1 v2=p2>
+2

< > ( ), - imho - , .

, :

String str = "<p1=v1 p2=v2> p3=v3 <p4=v4>";
Pattern insideTag = Pattern.compile("<(.+?)>");
Matcher m = insideTag.matcher(str);

while(m.find()) {
    str = str.replace(m.group(1), m.group(1).replaceAll("(\\w*)=(\\w*)", "$2=$1"));
}
System.out.println(str);

//prints: <v1=p1 v2=p2> p3=v3 <v4=p4>

, < >, , (\w*)=(\w*), .

<p1=v1 p2=v2 just some trash> p3=v3 <p4=v4>

<v1=p1 v2=p2 just some trash> p3=v3 <v4=p4>
0

Java \G, unsested < > ss : ((?:(?!\A|<)\G|<)[^<>]*?)(\w+)=(\w+)(?=[^<>]*?>)
(): $1$3=$2

Regex

 (                     # (1 start)
      (?:
           (?! \A | < )
           \G                    # Start at last match
        |  
           <                     # Or, <
      )
      [^<>]*? 
 )                     # (1 end)
 ( \w+ )               # (2)
 =
 ( \w+ )               # (3)
 (?= [^<>]*? > )       # There must be a closing > ahead

- Perl

$/ = undef;
$str = <DATA>;
$str =~ s/((?:(?!\A|<)\G|<)[^<>]*?)(\w+)=(\w+)(?=[^<>]*?>)/$1$3=$2/g;
print $str;
__DATA__
<p0=v0 p1=v1  p2=v2 ....>

<v0=p0 v1=p1  v2=p2 ....>
0

< and >:

String string = "<p0=v0 p1=v1 p2=v2> a=b c=d xyz=abc <foo=bar baz=bat>";
Pattern pattern1 = Pattern.compile("<[^>]+>");
Pattern pattern2 = Pattern.compile("(\\w+)=(\\w+)");
Matcher matcher1 = pattern1.matcher(string);
StringBuffer sbuf = new StringBuffer();
while (matcher1.find()) {
    Matcher matcher2 = pattern2.matcher(matcher1.group());
    matcher1.appendReplacement(sbuf, matcher2.replaceAll("$2=$1"));
}
matcher1.appendTail(sbuf);
System.out.println(sbuf);

:

<v0=p0 v1=p1 v2=p2> a=b c=d xyz=abc <bar=foo bat=baz>
0

All Articles