tags:

views:

53

answers:

2

How to group symbols for "not in range" expression in PHP?

  1. <li class="first">list item 1</li>
  2. <li class="second">list item 2</li>
  3. <li class="third">list item 3</li>
  4. <li class="fourth">list item 4</li>
  5. ...

I'd like to cath all li elements except one with class="second"

This does not work: /(<li[^(class="second")]+</li>)/xsU

A: 
Mark E
A: 

You are probably looking for something like this:

/<li(?:(?!class=['"]second['"])[^>])*>(?:(?!<\/li>).)*<\/li>/

The idea is based on using negative look-ahead assertions, grouped within capturing expressions. The complicated factors here are one of the main reasons people suggest against using regexp to parse HTML.

Explaining the RegExp:

/                - Start Regexp
 <li             - Match '<li'
 (?:             - Start Non-Capture Group
  (?!             - Start Negative Lookahead: 
                  - Ensure this group does not match (doesn't increment pointer either)
   class=          - Match 'class=' 
   ["']            - Match ' or "
   second          - Match 'second'
   ["']            - Match ' or "
  )               - End Negative Lookahead, 
                  - If it matched that whole segment, fail, otherwise:
  [^>]            - Match anything but '>'
 )*              - End Non-Capture Group - match 0 or more times
 >               - Match '>'
 (?:             - Start Non-Capture Group
  (?!             - Start negative lookahead
   <\/li>          - Match '</li>'
  )               - Ensure lookahead doesn't match, otherwise:
  .               - Capture any character
 )*              - End Non-Capture Group, match 0 or more times
 <\/li>          - Match '</li>'
/                - End RegExp
gnarf