我如何在这个正则表达式中自己编写一种转义字符?
How can I program a kind of escape character myself in this regular expression?
我想实现一个函数,将输入字符串中的各个字符串作为数组输出,例如 "str1|str2@str3":
function myFunc(string) { ... }
然而,对于输入 string
,只需要存在 str1
。 str2
和 str3
(及其分隔符)都是可选的。为此,我已经编写了一个执行某种拆分的正则表达式。我无法进行(正常)拆分,因为分隔符是不同的字符,而且 str1、str2 和 str3 的顺序也很重要。这有点适合我的正则表达式模式。现在,我正在努力如何扩展这种模式,以便您可以使用 \| 来转义这两个定界符或 \@.
我该如何解决这个问题?
var strings = [
'meaning',
'meaning|description',
'meaning@id',
'meaning|description@id',
'|description',
'|description@id',
'@id',
'meaning@id|description',
'sub1\|sub2',
'mea\|ning|descri\@ption',
'mea\@ning@id',
'meaning|description@identific\|\@ation'
];
var pattern = /^(\w+)(?:\|(\w*))?(?:\@(\w*))?$/ // works without escaping
console.log(pattern.exec(strings[3]));
根据问题定义,字符串0-3和8-11应该有效,其余无效。 myFunc(strings[3])
并且应该 return ['meaning','description','id']
并且 myFunc(strings[8])
应该 return [sub1\|sub2,null,null]
我的猜测是您希望拆分所有字符串,为此我们可能会在 char class 中添加这些分隔符,类似于:
([|@\]+)?([\w]+)
如果我们不这样做,我们可能想这样做以进行验证,否则我们的验证会随着组合的增加而变得非常复杂。
const regex = /([|@\]+)?([\w]+)/gm;
const str = `meaning
meaning|description
meaning@id
meaning|description@id
|description
|description@id
@id
meaning@id|description
sub1\|sub2
mea\|ning|descri\@ption
mea\@ning@id
meaning|description@identific\|\@ation`;
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++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
Demo
您需要允许 \[|@]
在模式中的 \w
旁边将您的 \w
替换为 (?:\[@|]|\w)
模式:
var strings = [
'meaning',
'meaning|description',
'meaning@id',
'meaning|description@id',
'|description',
'|description@id',
'@id',
'meaning@id|description',
'sub1\|sub2',
'mea\|ning|descri\@ption',
'mea\@ning@id',
'meaning|description@identific\|\@ation'
];
var pattern = /^((?:\[@|]|\w)+)(?:\|((?:\[@|]|\w)*))?(?:@((?:\[@|]|\w)*))?$/;
for (var s of strings) {
if (pattern.test(s)) {
console.log(s, "=> MATCHES");
} else {
console.log(s, "=> FAIL");
}
}
图案详情
^
- 字符串开始
((?:\[@|]|\w)+)
- 第 1 组:\
重复 1 次或多次,后跟 @
或 |
或单词 char
(?:\|((?:\[@|]|\w)*))?
- 匹配 1 次或 0 次出现的可选组
\|
- 一个 |
字符
((?:\[@|]|\w)*)
- 第 2 组:0 次或多次重复 \
后跟 @
或 |
或单词 char
(?:@((?:\[@|]|\w)*))?
- 匹配 1 次或 0 次出现的可选组
@
- 一个 @
字符
((?:\[@|]|\w)*)
第 3 组:0 次或多次重复 \
后跟 @
或 |
或单词 char
$
- 字符串结尾。
你要找的好像是这个?
((?:\@|\\||[^\|@])*)*
说明:
匹配包含 "\@"
、"\|"
或除 "@"
和 "|"
之外的任何字符的所有集合。
我想实现一个函数,将输入字符串中的各个字符串作为数组输出,例如 "str1|str2@str3":
function myFunc(string) { ... }
然而,对于输入 string
,只需要存在 str1
。 str2
和 str3
(及其分隔符)都是可选的。为此,我已经编写了一个执行某种拆分的正则表达式。我无法进行(正常)拆分,因为分隔符是不同的字符,而且 str1、str2 和 str3 的顺序也很重要。这有点适合我的正则表达式模式。现在,我正在努力如何扩展这种模式,以便您可以使用 \| 来转义这两个定界符或 \@.
我该如何解决这个问题?
var strings = [
'meaning',
'meaning|description',
'meaning@id',
'meaning|description@id',
'|description',
'|description@id',
'@id',
'meaning@id|description',
'sub1\|sub2',
'mea\|ning|descri\@ption',
'mea\@ning@id',
'meaning|description@identific\|\@ation'
];
var pattern = /^(\w+)(?:\|(\w*))?(?:\@(\w*))?$/ // works without escaping
console.log(pattern.exec(strings[3]));
根据问题定义,字符串0-3和8-11应该有效,其余无效。 myFunc(strings[3])
并且应该 return ['meaning','description','id']
并且 myFunc(strings[8])
应该 return [sub1\|sub2,null,null]
我的猜测是您希望拆分所有字符串,为此我们可能会在 char class 中添加这些分隔符,类似于:
([|@\]+)?([\w]+)
如果我们不这样做,我们可能想这样做以进行验证,否则我们的验证会随着组合的增加而变得非常复杂。
const regex = /([|@\]+)?([\w]+)/gm;
const str = `meaning
meaning|description
meaning@id
meaning|description@id
|description
|description@id
@id
meaning@id|description
sub1\|sub2
mea\|ning|descri\@ption
mea\@ning@id
meaning|description@identific\|\@ation`;
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++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
Demo
您需要允许 \[|@]
在模式中的 \w
旁边将您的 \w
替换为 (?:\[@|]|\w)
模式:
var strings = [
'meaning',
'meaning|description',
'meaning@id',
'meaning|description@id',
'|description',
'|description@id',
'@id',
'meaning@id|description',
'sub1\|sub2',
'mea\|ning|descri\@ption',
'mea\@ning@id',
'meaning|description@identific\|\@ation'
];
var pattern = /^((?:\[@|]|\w)+)(?:\|((?:\[@|]|\w)*))?(?:@((?:\[@|]|\w)*))?$/;
for (var s of strings) {
if (pattern.test(s)) {
console.log(s, "=> MATCHES");
} else {
console.log(s, "=> FAIL");
}
}
图案详情
^
- 字符串开始((?:\[@|]|\w)+)
- 第 1 组:\
重复 1 次或多次,后跟@
或|
或单词 char(?:\|((?:\[@|]|\w)*))?
- 匹配 1 次或 0 次出现的可选组\|
- 一个|
字符((?:\[@|]|\w)*)
- 第 2 组:0 次或多次重复\
后跟@
或|
或单词 char
(?:@((?:\[@|]|\w)*))?
- 匹配 1 次或 0 次出现的可选组@
- 一个@
字符((?:\[@|]|\w)*)
第 3 组:0 次或多次重复\
后跟@
或|
或单词 char
$
- 字符串结尾。
你要找的好像是这个?
((?:\@|\\||[^\|@])*)*
说明:
匹配包含 "\@"
、"\|"
或除 "@"
和 "|"
之外的任何字符的所有集合。