2

This string:

$subject = '\displaystyle{\ce{Cu^{2+}{(aq)}}+\ce{Zn{(s)}}\ce{->}\ce{Cu_{(s)}}+\ce{Zn^{2+}_{(aq)}}}'

I want to capture:

  • \ce{Cu^{2+}{(aq)}}
  • \ce{Zn{(s)}}
  • \ce{->}
  • \ce{Cu_{(s)}}
  • \ce{Zn^{2+}_{(aq)}}

My regex inspired by PHP - help with my REGEX-based recursive function

$pattern = '#\\\\ce\{(?:[^{}]|(?R))*}#';

I tried with

preg_match_all($pattern, $subject, $matches);
print_r($matches);
Array
(
    [0] => Array
        (
            [0] => \ce{->}
        )
 )

But it doesn't work as you can see...

2
  • do you want a new regex or just why its not working ? Whats your question ? Commented Jan 6, 2015 at 16:16
  • Yes, if you have a new regex... :) Commented Jan 6, 2015 at 16:16

2 Answers 2

4

Your can use this recursive regex:

(\\ce(\{(?:[^{}]|(?-1))*\}))

RegEx Demo

Here (?-1) recurses the 2nd subpattern that starts after \\ce.

Code:

$re = "/(
  \\\\ce
  (
    \\{
    (?:[^{}]|(?-1))*
    \\}
  )
)/x"; 

$str = 
 "\displaystyle{\ce{Cu^{2+}{(aq)}}+\ce{Zn{(s)}}\ce{->}\ce{Cu_{(s)}}+\ce{Zn^{2+}_{(aq)}}}"; 

if ( preg_match_all($re, $str, $m) )
   print_r($m[1]);

Output:

Array
(
    [0] => \ce{Cu^{2+}{(aq)}}
    [1] => \ce{Zn{(s)}}
    [2] => \ce{->}
    [3] => \ce{Cu_{(s)}}
    [4] => \ce{Zn^{2+}_{(aq)}}
)
Sign up to request clarification or add additional context in comments.

Comments

0

This works in my tests.
Note that \ce cannot be a sub-pattern without balanced braces.
So, this will fail \ce{Zn\cepp{(s)}},
and, this will pass \ce{Zn^{2+}\ce{Zn^{2+}_{(aq)}}_{(aq)}}
otherwise, why look for \ce{} in the first place ?

 #  '/\\\ce(\{(?:(?>(?!\\\ce)[^{}])+|(?R)|(?1))*\})/'

 \\ce
 (                  # (1 start)
      \{
      (?:
           (?>
                (?! \\ce )         # Not '\ce' ahead
                [^{}]              # A char, but not { or }
           )+
        |                   # or,
           (?R)               # Recurse whole expression
        |                   # or,
           (?1)               # Recurse group 1
      )*
      \}                
 )                  # (1 end)

1 Comment

@benoitMariaux - You're welcome. Though, looks like you accepted an answer that can match \ce without braces. Well, good luck parsing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.