正则表达式替换但忽略最后一个字符
Posted
技术标签:
【中文标题】正则表达式替换但忽略最后一个字符【英文标题】:Regex replace but ignore last character 【发布时间】:2020-02-28 11:53:22 【问题描述】:我正在尝试替换
/ok/how/are
与
$ok, $how, $are
使用正则表达式
str.replace(/\/([0-9a-zA-Z]+)/g, '\$$1,')
结果是
$ok, $how, $are,
我不能使用另一个语句来删除最后一个前导 ,
如果没有最后一个 ,
,我怎样才能得到期望的结果
【问题讨论】:
为什么必须是正则表达式? 是的,没有正则表达式,假设输入格式始终如您的示例所示,这很容易进行字符串操作 您可以使用您当前的解决方案,只切割最后一个逗号,例如:'/ok/how/are'.replace(/\/([0-9a-zA-Z]+)/g, '$$$1,').slice(0, -1)
我不能使用除了.replace之外的任何功能
【参考方案1】:
有几种可能的解决方案:如果是将 /
替换为 $
并用逗号分隔结果项,这可能是可行的。
第二种解决方案是在正则表达式中使用命名的捕获组(see here 和 sn-p)
console.log( `$$"/ok/how/are"
.split("\/")
.filter(v => /^[0-9a-zA-Z]+$/g.test(v))
.join(", $")` );
// use es2018 named capture groups in regex
// -----------------------------------------
console.log( "/ok/how/are".replace(/\/((?<end>\w+$)|(?<within>\w+))/g,
(...args) =>
const within, end = args[args.length-1];
return within ? `$$within, ` : `$$end`;
)
);
【讨论】:
我没有 jquery 或任何其他功能的选项,只有正则表达式和替换。 @Wasima。这个答案根本不使用jQuery
,它只是纯香草JS而已【参考方案2】:
您可以使用两个捕获的组,一个带有字符串锚点的结尾,另一个没有锚点并相应地替换值
let str = `/ok/how/are`
let final = str.replace(/\/([a-zA-Z\d]+)$|\/([a-zA-Z\d]+)/g, (_, g1, g2) => g1 ? `$$g1` : `$$g2, `)
console.log(final)
【讨论】:
您能解释一下吗?无条件使用它的任何可能性。我会用 vscode sn -p @Wasima。这里我们有两个捕获组,并基于捕获的组我们传递替换值。不,您要么需要条件,要么需要使用两个正则表达式【参考方案3】:如果您可以在 replace 中使用唯一的功能,您可以使用您的模式并将结尾的逗号替换为空格。
const regex = /\/([a-z0-9]+)/g;
let str = `/ok/how/are`;
str = str
.replace(regex, "$$$1, ")
.replace(/, $/, '');
console.log(str);
另一个没有正则表达式的选项可能是在正斜杠上使用split 的组合,在美元符号前使用map,在逗号和空格前使用join。
要在拆分后删除空条目,您可以使用例如.filter(Boolean)
let str = "/ok/how/are";
str = str.split("/")
.filter(Boolean)
.map(x => "$" + x)
.join(", ");
console.log(str)
【讨论】:
除了正则表达式和替换之外,我没有其他选择。 @Wasima。我已经使用另一个替换来更新我的答案以删除结尾的逗号和空格。 这很好,但不幸的是在 vscode sn-p 中我们不能使用第二个替换【参考方案4】:这是.replace
中基于 lambda/匿名函数的方法的另一种变体。这个正则表达式在前瞻中使用了一个捕获组,它断言我们前面是否有 /
或者它是字符串的结尾。
let str = '/ok/how/are';
var repl = str.replace(/\/([a-z\d]+)(?=(\/|$))/ig,
($0, $1, $2) => '$' + $1 + ($2 ? ", " : ""));
console.log(repl);
//=> "$ok, $how, $are"
详情:
\/([a-z\d]+)
:匹配 /
后跟 1+ 个字母(忽略大小写)或数字
(?=(\/|$))
:断言存在/
或字符串结尾并在第二个捕获组中捕获它的前瞻
($0, $1, $2)
:这里$0
将是完全匹配的字符串,$1, $2
是第一个和第二个捕获组
'$' + $1
:连接 $
和第一个捕获组
($2 ? ", " : "")
:使用三元运算符决定捕获组#2 或$2
是否为空。如果它不为空,则在最终输出中添加", "
,否则添加一个空字符串。
【讨论】:
能否请您解释一下这部分 ($0, $1, $2) => '$' + $1 + ($2 ? ", " : "") 肯定会在答案中添加解释。 你们太棒了,我们可以不使用 (_, g1, g2) => g1 吗?调理。我实际上是在尝试制作 vscode sn-p 并且它不接受条件 不幸的是,这将是一个有条件的事情或 2 次调用.replace
以上是关于正则表达式替换但忽略最后一个字符的主要内容,如果未能解决你的问题,请参考以下文章