KHansen
KHansen

Reputation: 930

Unexpected Output of .match() and regex

I am using match() and regex to receive an array of all occurrences of "Name". Name can be any string and is just a placeholder for this example.

As you can see in the first two iterations I receive the expected output. The third iteration however ignores the first \n and also outputs the previous line.

Any ideas why this happens?

$("#shortDescTextarea").on('keyup', function() {
  var currentVal = $(this).val();
  var allItemNames = currentVal.match(/\n[^:]+:/g);

  console.log(allItemNames);

});
textarea{height:250px;width:500px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="shortDescTextarea" class="form-control">|H|Header|/H|
Name: Value
Name: Value
|H|Header|/H|
Name:
</textarea>

Upvotes: 1

Views: 48

Answers (2)

Amadan
Amadan

Reputation: 198324

You should not match on \n, as it is not guaranteed to be there (e.g. if Name:... happens to be the first line of your text). Instead, use the m (multiline) flag, where ^ matches start of the line, however it comes to be. Similarly, you can use ? "non-greedy" modifier to make sure you don't cross over a colon, which makes it easy to use ., which doesn't match newlines, avoiding having to explicitly guard against them. Final result:

/^.*?:/gm

To capture both pre-colon and post-colon value:

let str = `
Name: Foo
Name: Bar
Header stuff I don't understand
Name: Quux
`;
let re = /^(.*?):\s*(.*)$/gm
results = [];
while (m = re.exec(str)) {
  results.push([m[1], m[2]]);
}
console.log(results);

Upvotes: 2

Shidersz
Shidersz

Reputation: 17190

One way you could fix this is adding the \n inside the brackets, like this:

currentVal.match(/\n[^:\n]+:/g);

Note that this /\n[^:]+:/g will capture all characters between a \n and : that do not include a : char, so this pattern \n|H|Header|/H|\nName: will be captured.

Example:

$("#shortDescTextarea").on('keyup', function()
{
    var currentVal = $(this).val();
    var allItemNames = currentVal.match(/\n[^:\n]+:/g);
    console.log(allItemNames);
});
textarea{height:250px;width:500px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="shortDescTextarea" class="form-control">|H|Header|/H|
Name: Value
Name: Value
|H|Header|/H|
Name:
</textarea>

Upvotes: 1

Related Questions