0

I'm trying to match the following string,

Apache/2.2.6 (Unix) mod_ssl/2.2.6 OpenSSL/0.9.7a DAV/2 PHP/5.2.13

with the following regex,

(?:Apache.(\w+))?.*(?:OpenSSL.([\w.]+))?.*(?:PHP.([\w.]+))?

Since the XXX/version pairs may not exist, so I added a ? after each non-capture matching groups

But only the first version string is matched,

var re = /(?:Apache.([\w.]+))?.*(?:OpenSSL.([\w.]+))?.*(?:PHP.([\w.]+))?/;
var captures = re.exec('Apache/2.2.6 (Unix) mod_ssl/2.2.6 OpenSSL/0.9.7a DAV/2 PHP/5.2.13');
console.log (captures);

// captures[1] = '2.2.6'
// captures[2] = undefined
// captures[3] = undefined

Any ideas? Removing the '?' works and I don't know why (works with perl)

EDIT

A valid regex that "works" could be (without the '?'),

(?:Apache.(\w+)).*(?:OpenSSL.([\w.]+)).*(?:PHP.([\w.]+))

2
  • @anubhava you mean the valid regex? Commented Sep 3, 2015 at 0:41
  • I meant few more samples of input data like Apache/2.2.6 (Unix) mod_ssl/2.2.6 OpenSSL/0.9.7a DAV/2 PHP/5.2.13 Commented Sep 3, 2015 at 5:31

1 Answer 1

2

.* is greedy so I'm not surprised it's not capturing beyond the first group. What surprises me is that it worked at all anywhere. Make those catch-alls lazy and un-group the non-capturing and capturing groups and it seems to work:

(?:Apache.)(\w+)?.*?(?:OpenSSL.)([\w.]+)?.*?(?:PHP.)([\w.]+)?
Sign up to request clarification or add additional context in comments.

Comments

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.