我有一个Javascript字符串:
let entries = `23-05-1990 Some heading
27-05-1990 Liar Liar
29-05-1990 Another Heading
30-05-1990 50/50
31-05-1990 My day`
使用regex,我需要处理这个字符串并生成两个数组:
// 1) date array:
date = ["23-05-1990","27-05-1990", "29-05-1990", "30-05-1990", "31-05-1990"]
// 2) headings array
headings = ["Some heading", "Liar Liar" ,"Another Heading", "50/50", "My day"]
到目前为止,这很简单:通过换行进行拆分,然后将每个单独的日期标题传递给regex。获取日期和标题,并将它们附加到各自的数组中。
但问题是我没有一个一致的数据格式。
有些数据是这种格式的。即标题在日期之前
`Liar Liar 27-05-1990
Another Heading 29-05-1990
50/50 30-05-1990
My day 31-05-1990 `
标题和日期之间可能有分隔符。
`23-05-1990 : Some heading
27-05-1990 : Yes Man`
`29-05-1990: Another Heading`
`30-05-1990 - 50/50
31-05-1990 - My day`
所以,日期和标题会在那里(我们不知道哪一个先出现(,但分隔符可能存在,也可能不存在。
此外,
分离器是下面列出的三种之一:
"quot;(空格(-&":">
标题不能以字母表或int以外的任何字符开始或结束。
您可以匹配以下正则表达式。日期字符串将在捕获组1或4中,另一个将为空。标题将在捕获组2或3中,另一个将为空。
^(?:(d{2}-d{2}-d{4}) *[-:]? *([A-Zd].*)|([A-Zd].*)(?<![ :-]) *[-:]? *(d{2}-d{2}-d{4}))$
启动发动机!
如链接所示,"$1$4"
返回日期字符串,"$2$3"
返回标题。
Javascript的正则表达式引擎执行以下操作。
^ : assert beginning of string
(?: : begin non-capture group
(d{2}-d{2}-d{4}) : match date and save to capture group 1
[ ]*[-:]?[ ]* : match 0+ spaces, optional '-' or ':',
0+ spaces
([A-Zd].*) : match heading and save to capture group 2
| : or
([A-Zd].*) : match heading and save to capture group 3
(?<![ :-]) : negative lookbehind asserts previous
character is neither ' ', ':' nor '-'
[ ]*[-:]?[ ]* : match 0+ spaces, optional '-' or ':',
0+ spaces
(d{2}-d{2}-d{4}) : match date and save to capture group 4
) : end non-capture group
$ : assert end of string
这是有效的,但它不考虑重复,所以如果这是一个问题,那么您可以在之后过滤掉这些,或者在数组中使用键/值对。
while循环的一部分来自regex101.com
const regexes = [
/((?<date>d{2}-d{2}-d{4})[ :-]+(?<title>.*)[rn])/gm,
/(?<title>.*)[ :-]+((?<date>d{2}-d{2}-d{4})[rn])/gm
];
const str = `23-05-1990 Some heading
27-05-1990 Liar Liar
29-05-1990 Another Heading
30-05-1990 50/50
31-05-1990 My day
Liar Liar 27-05-1990
Another Heading 29-05-1990
50/50 30-05-1990
My day 31-05-1990
23-05-1990 : Some heading
27-05-1990 : Yes Man
29-05-1990: Another Heading
30-05-1990 - 50/50
31-05-1990 - My day`;
let output = [];
regexes.forEach(regex => {
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
output.push([m.groups.date.trim(), m.groups.title.trim()]);
}
});
console.log(output);
输出为:
[
[ '23-05-1990', 'Some heading' ],
[ '27-05-1990', 'Liar Liar' ],
[ '29-05-1990', 'Another Heading' ],
[ '30-05-1990', '50/50' ],
[ '31-05-1990', 'My day' ],
[ '23-05-1990', 'Some heading' ],
[ '27-05-1990', 'Yes Man' ],
[ '29-05-1990', 'Another Heading' ],
[ '30-05-1990', '50/50' ],
[ '27-05-1990', 'Liar Liar' ],
[ '29-05-1990', 'Another Heading' ],
[ '30-05-1990', '50/50' ],
[ '31-05-1990', 'My day' ]
]