我正在编写一个微模板脚本,其中部分字符串被替换为对象选项。这是一个简短的例子:
var person = {name:"Smith",age:43};
var string = "I am {name} and I am {age} years old";
document.write(string.replace(/{([\s\S]+?)}/g,(person['$1']||"")));
document.write("<br/>");
document.write(string.replace(/{([\s\S]+?)}/g
, function($0,$1){return person[$1]||"";}));
同样在JS Fiddle
第二个表达式可以正常工作,但不是第一个表达式。谁有人解释原因?我认为$1
可以直接用作字符串中的后向引用。
答案 0 :(得分:1)
$1
,$2
,...,$&
只有在传递给replace
的字符串值的一部分时才能使用:
string.replace(/{([\s\S]+?)}/g, '$1(matched)');
// result: "I am name(matched) and I am age(matched) years old"
但是,第一个片段是有效的:
document.write(string.replace(/{([\s\S]+?)}/g,""));
那是因为(person['$1']||"")
不是可以按原样传递的值。这是一个属性查找和逻辑 - 或将首先评估它们的结果值 - ""
- 将实际传递给replace
。
为了能够在之后评估表达式,你必须使用一个函数来延迟评估,就像在第二个片段中一样。
答案 1 :(得分:1)
这对我来说很有意义,我的意思是你看看这个:
person['$1']
你基本上是说“给我$1
里面的对象person
”,在这种情况下是undefined
。我想它试图在正则表达式捕获组之前评估对象。这就是为什么你有功能替换,它适用于这种情况。
答案 2 :(得分:1)
RegExp.replace
方法尝试仅在字符串中解析$n
个表达式(以及$&
和其他几个表达式 - 仅查看here完整列表)。但是person['$1']
之类的东西不是字符串 - 它是一个表达式,可能(或可能不是)被评估为字符串。只有在此评估之后,才会解析反向引用“标记”。
我认为replace
中的回调是你的唯一正常方式。
答案 3 :(得分:0)
第二个正则表达式中$ 1左右没有单引号。