Martin
Martin

Reputation: 22760

PCRE regex capture group can be numbers or letters but can't be just numbers

I have seen a host of questions very similar to this but they're not able to quite collect what I'm looking for.

I have a search system for finding PDO named placeholders in an SQL string.

PDO placeholders can be A-z, 0-9, or _ and always begin with :. However, in some circumstances date and time values also appear which naturally use : (12:35).

I need to check to find placeholders that match the PDO criteria but which are not just numeric.

Can I do this in a single Regex?

The regex I have developed at the moment is:

/:(?:[A-Z_]*)(?=[0-9]*)/gmi

But this cuts off when any digit is found, see the below example SQL:

SELECT name, horse, id, DATE_FORMAT(Nee.datetimed, '12:12:12 @ %D') as del_time 
     FROM members WHERE biztype LIKE CONCAT('%',:bizb,'%') 
     AND (locate LIKE '%hos%' OR locate LIKE '%all%') 
     AND bizcat LIKE CONCAT('%',:catb7,'%') ORDER BY `status` DESC, RAND()

I need to catch :catb7 and :bizb but ignore the time values.

My Regex above catches :bizb and catb but that catch is incorrect as it chops off the 7.

 /:(?:[A-Z_]*(?:[0-9]*))/gmi

Catches :12 and :12 which is incorrect.

 /:(?:[A-Z_]*)(?=[0-9]*)/gmi 

Catches : as well which is incorrect.

Various tweaks and changes to the capture groups can't seem to find the correct result: Looking for:

:<any letter or number or underscore, any length, must contain at least one letter or underscore>

Valid catches:

  :adbcd
  :5fedg
  :56_gt
  :der
  :9_6

INVALID catches:

 :12 
 :1
 :%D [MySQL date formatting]

Upvotes: 2

Views: 80

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626952

You can use

\B:(?!\d+\b)\w+

See the regex demo.

Details:

  • \B - a non-word boundary position (start of string or a non-word char must appear immediately to the left of the current location)
  • : - a colon
  • (?!\d+\b) - a negative lookahead that fails the match if there are one or more digits followed with a word boundary immediately to the right of the current location
  • \w+ - one or more word chars (letters/digit/underscores)

Upvotes: 2

Related Questions