GFL
GFL

Reputation: 1424

Regular Expression That Contains At Least One Of Each

I'm trying to capitalize "words" that have at least one number, letter, and special character such as a period or dash.

Things like: 3370.01b, 6510.01.b, m-5510.30, and drm-2013-c-004914.

I don't want it to match things like: hello, sk8, and mixed-up

I'm trying to use lookaheads, as suggested, but I can't get it to match anything.

$output = preg_replace_callback('/\b(?=.*[0-9]+)(?=.*[a-z]+)(?=.*[\.-]+)\b/i', function($matches){return strtoupper($matches[0]);}, $input);

Upvotes: 3

Views: 2873

Answers (3)

ArtisticPhoenix
ArtisticPhoenix

Reputation: 21671

I don't think you never captured anything to put into matches...

$input = '3370.01b foo';
$output = preg_replace_callback('/(?=.*[0-9])(?=.*[a-z])(\w+(?:[-.]\w+)+)/i', function($matches){return strtoupper($matches[0]);}, $input);

echo $output;

Output

3370.01B foo

Sandbox

https://regex101.com/r/syJWMN/1

Upvotes: 0

Alex
Alex

Reputation: 17289

Regular expression:

https://regex101.com/r/sdmlL8/1

(?=.*\d)(.*)([-.])(.*)

PHP code:

https://ideone.com/qEBZQc

$input = '3370.01b';
$output = preg_replace_callback('/(?=.*\d)(.*)([-.])(.*)/i', function($matches){return strtoupper($matches[0]);}, $input);

Upvotes: 0

Pushpesh Kumar Rajwanshi
Pushpesh Kumar Rajwanshi

Reputation: 18357

You can use this regex to match the strings you want,

(?=\S*[a-z])(?=\S*\d)[a-z\d]+(?:[.-][a-z\d]+)+

Explanation:

  • (?=\S*[a-z]) - This look ahead ensures that there is at least an alphabet character in the incoming word
  • (?=\S*\d) - This look ahead ensures that there is at least a digit in the incoming word
  • [a-z\d]+(?:[.-][a-z\d]+)+ - This part captures a word contain alphanumeric word containing at least one special character . or -

Online Demo

Here is the PHP code demo modifying your code,

$input = '3370.01b, 6510.01.b, m-5510.30, and drm-2013-c-004914 hello, sk8, and mixed-up';
$output = preg_replace_callback('/(?=\S*[a-z])(?=\S*\d)[a-z\d]+(?:[.-][a-z\d]+)+/i', function($matches){return strtoupper($matches[0]);}, $input);
echo $output;

Prints,

3370.01B, 6510.01.B, M-5510.30, and DRM-2013-C-004914 hello, sk8, and mixed-up

Upvotes: 4

Related Questions