tags:

views:

815

answers:

6

I'm trying in vain to write a regular expression to match valid ssh connection strings.

I really only need to recognise strings of the format:

  • user@hostname:/some/path

but it would be nice to also match an implicit home directory:

  • user@hostname:

I've so-far come up with this regex:

/^[:alnum:]+\@\:(\/[:alnum:]+)*$/

which doesn't work as intended.

Any suggestions welcome before my brain explodes and I start speaking in line noise :)

A: 

Bracket expressions go inside their own brackets. You are matching any one of colon, 'a', 'l', 'm', 'n', or 'u'.

And like Pax said, you missed the hostname. But the bracket expressions are still wrong.

Cirno de Bergerac
+2  A: 

Your supplied regex doesn't have the hostname section. Try:

/^[:alnum:]+\@[:alnum:\.]\:(\/[:alnum:]+)*$/

or

/^[A-Za-z][A-Za-z0-9_]*\@[A-Za-z][A-Za-z0-9_\.]*\:(\/[A-Za-z][A-Za-z0-9_]*)*$/

since I don't trust alnum without double brackets.

Also, :alnum: may not give you the required range for your sections. You can have "." characters in your host name and may also need to allow for "_" characters. And it's rare I've seen usernames or hostnames start with a non-alphabetic.

Just as a side note, I try to avoid the enhanced regexes since they don't run on all regex engines (I've been using UNIX for a long time). Unfortunately that makes my regexes ungainly (see above) and not overly internationalizable. Apologies for that.

paxdiablo
A: 
Kent Fredric
A: 

After some more revisions I'm using:

/^\w+\@(\w|\.)+\:(\/\w+)*$/

which seems to match my test cases and accounts for hostnames, FQDNs and IP addresses in the host portion. It also makes the path after the colon optional to allow for implicit home directories.

Thanks for the help so far - I didn't spot the lack of hostname until it was pointed out.

Can hostnames start with a "."?
paxdiablo
@pax , no, i wondered about * aliases and default search resolution, but even with both of those pointing to a seemingly viable place, . as the first part fails to resolve.
Kent Fredric
A: 

OK, further revision to:

/^\w+\@(\w|\.)+\:(\/(\w|.)+)*$/

to account for the . that might be present in a file name.

A: 

Final go:

/^\w+\@(\w|\.)+\:(\/(\w|.)+\/?)*$/

This also allows for an optional trailing slash.

Sam, it would be a better idea to edit your original answer to include these updates rather than post more answers.
paxdiablo