1

I have program:

var str = "ac.def=1 and xy.z.kt='10' and k.t=1 or xy.z.kt.lm='10'";
var regex = new RegExp('^[a-zA-Z0-9,]*[.]{1}[^=]');
var result = str.split(" ").filter((elem, index) => {
    return regex.test(elem);
})

console.log(result);

I get result as: ["ac.def=1", "xy.z.kt='10'", "k.t=1", "xy.z.kt.lm='10'"]

but I need to get only : ["abc.def=1", "k.t=1"]


it is said that my question is possible duplicate of Learning Regular Expressions so lets close stackoverflow forever, because all questions about software programming has an answer in their own official documents.

Please be careful when marking a question as a possible duplicate of an official documents. Otherwise we should close all questions about regex since Learning Regular Expressions is enough to solve all problems about regex. Right?

Ismail Sahin
  • 2,640
  • 5
  • 31
  • 58
  • Possible duplicate of [Learning Regular Expressions](https://stackoverflow.com/questions/4736/learning-regular-expressions) – Biffen Feb 14 '19 at 11:02
  • 1
    Do you want to select `ac.def=1.5` or `def=1.5` too? – Gurmanjot Singh Feb 14 '19 at 11:16
  • @Potato No, because there are 2 dots – Wiktor Stribiżew Feb 14 '19 at 11:17
  • @WiktorStribiżew Looking at the regex provided by him, it seems that he wants a single dot only to the left side of assignment `=` irrespective of what how many dots are at the right side of `=`. Not sure though... – Gurmanjot Singh Feb 14 '19 at 11:21
  • @Potato Fair enough, I assumed the *word* is a streak of non-whitespace chars here (judging by the `split(" ")` method), so a single dot is allowed anywhere inside. Then, if the single dot should come before `=`, this requirement must be reflected in the title - it is a very important bit. – Wiktor Stribiżew Feb 14 '19 at 11:26
  • 1
    Then, `/^[^.=]*\.[^.=]*=/` will do. – Wiktor Stribiżew Feb 14 '19 at 11:28

1 Answers1

3

You may use the /^[^.]*\.[^.]*$/ regex:

var str = "ac.def=1 and xy.z.kt='10' and k.t=1 or xy.z.kt.lm='10'";
var regex = /^[^.]*\.[^.]*$/;
var result = str.split(" ").filter((elem, index) => {
    return regex.test(elem);
})

console.log(result);

Pattern details

  • ^ - start of string
  • [^.]* - 0+ chars other than .
  • \. - a dot
  • [^.]* - 0+ chars
  • $ - end of string.

See the regex demo.

Alternative, single-regex, solution

You may collect your matches using a single regex like

/(?:^|\s)([^.\s]*\.[^.\s]*)(?!\S)/g

See the regex demo.

Details

  • (?:^|\s) - a non-capturing group matching start of string or whitespace
  • ([^.\s]*\.[^.\s]*) - Capturing group 1:
    • [^.\s]* - 0+ chars other than a . and whitespace
    • \. - a dot
    • [^.\s]* - 0+ chars other than a . and whitespace
  • (?!\S) - no non-whitespace allowed immediately to the right of the current location (a whitespace or end of string can appear to the right)

JS demo:

var s = "ac.def=1 and xy.z.kt='10' and k.t=1 or xy.z.kt.lm='10'";
var results = [];
s.replace(/(?:^|\s)([^.\s]*\.[^.\s]*)(?!\S)/g, ($0, $1) => results.push($1));
console.log(results);

If there must be a single dot before =, use

/^[^.=]*\.[^.=]*=/

within your code. See the regex demo. The difference is that the regex no longer has $ at the end, = is at the end as it is enough to stop checking there, and = chars are added to the negated character classes to prevent them from matching across these symbols.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563