K Split X
K Split X

Reputation: 4797

Regex to match string separated by dots, can only contain alphanumeric, hypens, underscores, dots

I need a regex that will match the following:

a.b.c

a0.b_.c

a.bca._cda.dca-fb

Notice that it can contain numbers, but the groups are separeted by dots. The characters allowed are a-zA-z, -, _, 0-9

The rule is that it cannot start with a number, and it cannot end with a dot. i.e, the regex should not match

0a.b.c

a.b.c.d.

I have come up with a regex, which seems to work on regex101, but not javascript

([a-zA-Z]+.?)((\w+).)*(\w+)

enter image description here`

But does not seem to work in js:

var str = "a.b.c"

if (str.match("([a-zA-Z]+.?)((\w+).)*(\w+)")) {
  console.log("match");
} else {
  console.log("not match");
}

// says not match

Upvotes: 2

Views: 5114

Answers (2)

The fourth bird
The fourth bird

Reputation: 163642

Your regex matches your values if you use anchors to assert the start ^ and the end $ of the line.

As an alternative you might use:

^[a-z][\w-]*(?:\.[\w-]+)*$

This will assert the start of the line ^, matches a word character \w (which will match [a-zA-Z0-9_]) or a hyphen in a character class [\w-].

Then repeat the pattern that will match a dot and the allowed characters in the character class (?:\.[\w-]+)* until the end of the line $

const strings = [
  "a.b.c",
  "A.b.c",
  "a0.b_.c",
  "a.bca._cda.dca-fb",
  "0a.b.c",
  "a.b.c.d."
];
let pattern = /^[a-z][\w-]*(?:\.[\w-]+)*$/i;

strings.forEach((s) => {
  console.log(s + " ==> " + pattern.test(s));
});

If the match should not start with a digit but can start with an underscore or hypen you might use:

^[a-z_-][\w-]*(?:\.[\w-]+)*$

Upvotes: 2

user7637745
user7637745

Reputation: 985

Use forward slashes / and paste the regex code between them from online regex testers, when you use JavaScipt.

Here are, what I've changed in your regex pattern:

  • added ^ at the beginning of your regex to match the beginning of the input
  • added $ at the end to match the end of the input
  • removed A-Z and added the i modifier for case-insensitive search (this is optional).

Also, when you use regex101, make sure to select JavaScript Flavor, when creating/testing your regex for JavaScript.

var pattern = /^([a-z]+.?)((\w+).)*(\w+)$/i;

// list of strings, that should be matched
var shouldMatch = [
  'a.b.c',
  'a0.b_.c',
  'a.bca._cda.dca-fb'
];

// list of strings, that should not be matched
var shouldNotMatch = [
  '0a.b.c',
  'a.b.c.d.'
];

shouldMatch.forEach(function (string) {
  if (string.match(pattern)) {
    console.log('matched, as it should: "' + string + '"');    
  } else {
    console.log('should\'ve matched, but it didn\'t: "' + string + '"');
  }
});

shouldNotMatch.forEach(function (string) {
  if (!string.match(pattern)) {
    console.log('didn\'t match, as it should: "' + string + '"');
  } else {
    console.log('shouldn\'t have matched, but it did: "' + string + '"');
  }
});

More on regexes in JavaScript

Upvotes: 1

Related Questions