首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript正则表达式替换字符串中的最后一个模式?

JavaScript正则表达式替换字符串中的最后一个模式?
EN

Stack Overflow用户
提问于 2020-03-10 20:48:54
回答 3查看 85关注 0票数 0

我有一根看起来像

代码语言:javascript
复制
var std = new Bammer({mode:"deg"}).bam(0, 112).bam(177.58, (line-4)/2).bam(0, -42)
  .ramBam(8.1, 0).bam(8.1, (slot_height-thick)/2)

我想在最后一个.bam().ramBam()周围加上一个标签。

代码语言:javascript
复制
str.replace(/(\.(ram)?bam\(.*?\))$/i, '<span class="focus">$1</span>');

我希望能得到:

代码语言:javascript
复制
new Bammer({mode:"deg"}).bam(0, 112).bam(177.58, (line-4)/2).bam(0, -42).ramBam(8.1, 0)<span class="focus">.bam(8.1, (slot_height-thick)/2)</span>

但不知何故,我继续与非贪婪的参数战斗,它用span标签包装了新的Bammer之后的一切。在$之前也尝试了一个问号,以使小组不贪婪。

我希望能简单地做到这一点,使用bamramBam,我认为正则表达式是最简单的解决方案,但我认为我错了。

我哪里出问题了?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-03-10 23:20:14

您可以使用以下正则表达式:

代码语言:javascript
复制
(?!.*\)\.)(\.(?:bam|ramBam)\(.*\))$

演示

代码语言:javascript
复制
(?!.*\)\.)         # do not match ').' later in the string
(                  # begin capture group 1                   
  .\               # match '.'
  (?:bam|ramBam)   # match 'bam' or 'ramBam' in non-cap group
  \(.*\)           # match '(', 0+ chars, ')'
)                  # end capture group 1
$                  # match end of line

对于问题中给出的示例,负前瞻性(?!.*\)\.)将内部指针移动到子字符串之前:

代码语言:javascript
复制
.bam(8.1, (slot_height-thick)/2)

因为这是字符串后面没有子字符串).的第一个位置。

如果没有行尾锚$并且字符串结束:

代码语言:javascript
复制
...0).bam(8.1, (slot_height-thick)/2)abc

然后,仍将进行替换,从而生成一个字符串,该字符串的结尾为:

代码语言:javascript
复制
...0)<span class="focus">.bam(8.1, (slot_height-thick)/2)</span>abc

如果字符串没有以预期捕获组的内容结束,则包括行尾锚将防止替换。

票数 2
EN

Stack Overflow用户

发布于 2020-03-10 21:10:51

使用要求:

代码语言:javascript
复制
/\.((?:ram)?[bB]am\([^)]*\))(?!.*\.(ram)?[bB]am\()/
  1. \.匹配周期。
  2. (?:ram)?可选择匹配非捕获组中的ram
  3. [bB]ambamBam匹配。
  4. \((匹配。
  5. [^)]*匹配0或多个字符,只要它们不是)
  6. ))匹配。项目2至6.置于捕获组1中。
  7. (?!.*\.(ram)?[bB]am\() --这是一个负的前瞻性断言,说明字符串的其余部分不包含.ram(.rambam(.ramBam(的进一步实例,因此这是最后一个实例。

见Regex Demo

代码语言:javascript
复制
let str = 'var std = new Bammer({mode:"deg"}).bam(0, 112).bam(177.58, 0).bam(0, -42).ramBam(8.1, 0).bam(8.1, slot_height)';
console.log(str.replace(/\.((?:ram)?[bB]am\([^)]*\))(?!.*\.(ram)?[bB]am\()/, '<span class="focus">.$1</span>'));

更新

JavaScript正则表达式引擎不够强大,无法处理嵌套括号。解决这个问题的唯一方法是,假设在最后调用bamramBam之后,字符串中没有多余的右括号。然后,在使用\([^)]*\)扫描括号大小的表达式时,如果不能选择最后的括号,我们现在必须使用\(.*\)扫描所有内容,直到最后的括号。至少我不知道其他方法。但这也意味着,我使用负前瞻性来确定ramramBam的最终实例的方式需要稍作调整。在开始执行任何贪婪的匹配之前,我需要确保拥有ramramBam的最后实例:

代码语言:javascript
复制
(\.(?:bam|ramBam)(?!.*\.(bam|ramBam)\()\((.*)\))

见Regex Demo

  1. \..匹配。
  2. (?:bam|ramBam)匹配bam或ramBam。
  3. (?!.*\.(bam|ramBam)\()断言第1项是最终实例
  4. \((匹配。
  5. (.*)贪婪地匹配一切直到..。
  6. 最后的\) )
  7. )项目1至6.放置在捕获组1中。

代码语言:javascript
复制
let str = 'var std = new Bammer({mode:"deg"}).bam(0, 112).bam(177.58, (line-4)/2).bam(0, -42) .ramBam(8.1, 0).bam(8.1, (slot_height-thick)/2)';
console.log(str.replace(/(\.(?:bam|ramBam)(?!.*\.(bam|ramBam)\()\((.*)\))/, '<span class="focus">$1</span>'));

票数 2
EN

Stack Overflow用户

发布于 2020-03-10 20:59:56

非贪婪的标志并不完全正确,因为这只会使正则表达式选择最小数量的字符来适应模式。我建议你用这样的负前瞻做点什么:

代码语言:javascript
复制
str.replace(/(\.(?:ram)?[Bb]am\([^)]*\)(?!.*(ram)?[Bb]am))/i, '<span class="focus">$1</span>');

请注意,这只会替换最后一个函数名(bamramBam),而不是两者都替换。您需要采取一种稍微不同的方法来替换这两种方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60625719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档