正则表达式替换但忽略最后一个字符

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

以上是关于正则表达式替换但忽略最后一个字符的主要内容,如果未能解决你的问题,请参考以下文章

用于忽略自定义转义字符的正则表达式模式

如何通过python忽略正则表达式中的html注释标签

(php) 正则表达式删除注释但忽略字符串中的出现

java中怎么替换string中的某个字符

Java正则表达式用逗号分割字符串,但忽略引号和括号[重复]

如何修改一个正则表达式的匹配方式