Reputation: 1016
I am parsing some key value pairs that are separated by colons. The problem I am having is that in the value section there are colons that I want to ignore but the split
function is picking them up anyway.
sample:
Name: my name
description: this string is not escaped: i hate these colons
date: a date
On the individual lines I tried this line.split(/:/, 1)
but it only matched the value part of the data. Next I tried line.split(/:/, 2)
but that gave me ['description', 'this string is not escaped']
and I need the whole string.
Thanks for the help!
Upvotes: 13
Views: 13371
Reputation: 730
function splitOnce(str, sep) {
const idx = str.indexOf(sep);
return [str.slice(0, idx), str.slice(idx+1)];
}
splitOnce("description: this string is not escaped: i hate these colons", ":")
Upvotes: 0
Reputation: 206151
To split a string with multiple i.e. columns :
only at the first column occurrence
use Positive Lookbehind (?<=)
const a = "Description: this: is: nice";
const b = "Name: My Name";
console.log(a.split(/(?<=^[^:]*):/)); // ["Description", " this: is: nice"]
console.log(b.split(/(?<=^[^:]*):/)); // ["Name", " My Name"]
it basically consumes from Start of string ^
everything that is not a column [^:]
zero or more times *
. Once the positive lookbehind is done, finally matches the column :
.
If you additionally want to remove one or more whitespaces following the column,
use /(?<=^[^:]*): */
Upvotes: 0
Reputation: 22536
Use the greedy operator (?
) to only split the first instance.
line.split(/: (.+)?/, 2);
Upvotes: 15
Reputation: 1004
May be this approach will be the best for such purpose:
var a = line.match(/([^:\s]+)\s*:\s*(.*)/);
var key = a[1];
var val = a[2];
So, you can use tabulations in your config/data files of such structure and also not worry about spaces before or after your name-value delimiter ':'
.
Or you can use primitive and fast string functions indexOf
and substr
to reach your goal in, I think, the fastest way (by CPU and RAM)
for ( ... line ... ) {
var delimPos = line.indexOf(':');
if (delimPos <= 0) {
continue; // Something wrong with this "line"
}
var key = line.substr(0, delimPos).trim();
var val = line.substr(delimPos + 1).trim();
// Do all you need with this key: val
}
Upvotes: 0
Reputation: 39
Slightly more elegant:
a = line.match(/(.*?):(.*)/);
key = a[1];
val = a[2];
Upvotes: 1