简体   繁体   中英

Regex to match user and user@domain

A user can login as "user" or as "user@domain". I only want to extract "user" in both cases. I am looking for a matcher expression to fit it, but im struggling.

final Pattern userIdPattern = Pattern.compile("(.*)[@]{0,1}.*");
final Matcher fieldMatcher = userIdPattern.matcher("user@test");
final String userId = fieldMatcher.group(1)

userId returns "user@test". I tried various expressions but it seems that nothing fits my requirement :-(

Any ideas?

If you use "(.*)[@]{0,1}.*" pattern with .matches() , the (.*) grabs the whole line first, then, when the regex index is still at the end of the line, the [@]{0,1} pattern triggers and matches at the end of the line because it can match 0 @ chars, and then .* again matches at that very location as it matches any 0+ chars. Thus, the whole line lands in your Group 1.

You may use

String userId = s.replaceFirst("^([^@]+).*", "$1");

See the regex demo .

Details

  • ^ - start of string
  • ([^@]+) - Group 1 (referred to with $1 from the replacement pattern): any 1+ chars other than @
  • .* - the rest of the string.

A little bit of googling came up with this:

(.*?)(?=@|$)

Will match everthing before an optional @

I would suggest keeping it simple and not relying on regex in this case if you are using java and have a simple case like you provided.

You could simply do something like this:

String userId = "user@test";

if (userId.indexOf("@") != -1)
    userId = userId.substring(0, userId.indexOf("@"));

// from here on userId will be "user".

This will always either strip out the "@test" or just skip stripping it out when it is not there.

Using regex in most cases makes the code less maintainable by another dev in the future because most devs are not very good with regular expressions, at least in my experience.

You included the @ as optional, so the match tries to get the longest user name. As you didn't put the restriction of a username is not allowed to have @ s in it, it matched the longest string.

Just use:

[^@]*

as the matching subexpr for usernames (and use $0 to get the matched string)

Or you can use this one that can be used to find several matches (and to get both the user part and the domain part):

\b([^@\s]*)(@[^@\s]*)?\b

The \\b force your string to be tied to word boundaries, then the first group matches non-space and non- @ chars (any number, better to use + instead of * there, as usernames must have at least one char) followed (optionally) by a @ and another string of non-space and non- @ chars). In this case, $0 matches the whole email addres, $1 matches the username part, and $2 the @domain part (you can refine to only the domain part, adding a new pair of parenthesis, as in

b([^@\s]*)(@([^@\s]*))?\b

See demo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM