tags:

views:

63

answers:

2

This is for make something similar to "templates" in MediaWiki with PHP in order to make the parameters between nested templates work.

Is possible with a regex to capture all occurrences of a character between braces but ignoring occurrences of it if it occurs in a nested group of braces?

| {{ | {{ | }} | | }} |

Highlighted:

| {{ *|* {{ | }} *|* *|* }} |
A: 
m/.*{{([^{]+)}}/

that would capture a group between {{ and }} so long as '{' wasn't present - syntax is perl

though this is better done with a parser

edited again.

Mimisbrunnr
@Mimisbrunnr, I think you intend on having that `+` inside the capture group.
macek
Your posted regex captures this: "{{ | }} | | }}" from | {{ | {{ | }} | | }} |. The first pipe is missed...
drewk
A: 

No, you must write a context-free grammar (or Perl recursive regexps) to parse it. What are the ignored nested templates replaced by?

The parser will look like this in pseudocode:

input = "| {{ | {{ | }} | | }} |", pointer = 0;
char = '', results = [];

read_next_char() {
  return input[++ pointer];
}

go_back_one_char() {
  pointer --;
}

while (char = read_next_char()) {
  if (char == '{') {
    if (read_next_char() == '{') InsideBraces();
    else go_back_one_char();
  }
}

InsideBraces(skipping=false) {
  result = "";
  while (char = read_next_char()) {
    if (char == '{') {
      if (read_next_char() == '}') InsideBraces();
      else go_back_one_char();
    } else if (char == '}') {
      if (read_next_char() == '}') break;
      else go_back_one_char();
    } else {
      result += char;
    }
  }
  if (!skipping) results.push(result);
}
SHiNKiROU
PHP also has the capability to do recursive regex matching.
Bart Kiers