简体   繁体   English

javascript:regexp以匹配未包含在自定义标签中的单词

[英]javascript: regexp to match a word that is NOT enclosed in custom tags

I need to match and replace all occurrences of 'word' that are not enclosed within the tags :$ and $: in a string. 我需要匹配并替换所有未包含在字符串:$$:中的'word'单词。 There may be other characters within the tags beside 'word'. 标签中的“单词”旁边可能还有其他字符。

So, say I have the string 所以,说我有字符串

abc word hey :$ my word $:

And I need to replace word with letter ; 而且我需要用letter代替word ; Essentially I want to obtain the following string: 本质上,我想获取以下字符串:

abc letter hey :$ my word $:

What is the best way to achieve that in JavaScript? 用JavaScript实现这一目标的最佳方法是什么?

Further information: 更多信息:

tags won't be nested. 标签不会嵌套。 the string may contain the characters ':' and '$' singularly. 该字符串可以包含单个字符“:”和“ $”。 In this case they should be treated as simple characters and not as a tag. 在这种情况下,应将它们视为简单字符而不是标签。

I wasn't able to specify a RegExp for that, so here is a more imperative approach that does this - http://jsfiddle.net/dNhLm/ 我无法为此指定RegExp,因此这是一种更强制性的方法-http://jsfiddle.net/dNhLm/

var text = "abc word hey :$ my word $:";
var replace = function(text, pattern, replacement) {
  var parts = [];
  // This will split the string into parts. The ones that has :$ we will have to proceed further and ignore
  var splitByEnd = text.split('$:');    
  for (i = 0, l = splitByEnd.length; i < l; i++) {
      // Here we should have at most 2 parts. The left one will be outside of the :$,$: pairs and is the
      // one we will apply the replacement. The right one if present will be between the :$,$: pairs and is
      // not a subject of replacement.
      var splitByStart = splitByEnd[i].split(':$');
      splitByStart[0] = splitByStart[0].replace(pattern, replacement);

      parts.push(splitByStart.join(':$'));
  }

  return parts.join('$:');
}

alert(replace(text, 'word', 'letter'));

I'm not sure regex is the right tool for the job here (a parser is likely more appropriate), but I guess one simple solution would be to cut out the bits covered by the tags, replacing all words, then replacing the tags. 我不确定正则表达式是否适合此处的工作(解析器可能更合适),但是我猜一个简单的解决方案是切掉标签所覆盖的位,替换所有单词,然后替换标签。 Something along the lines of this (which won't support nested tags, but should otherwise work): 与此类似的东西(它不支持嵌套标签,但应该可以工作):

var line = 'abc word hey :$ my word $: word :$ my word $:';
var tags = [];
var index = 0;
while (line.match(/:\$.*\$:/)) {
    var start = line.indexOf(':$');
    var end = line.indexOf('$:', start);
    var tag = line.substring(start, end + 2);
    line = line.replace(tag, '$tag' + index + '$');
    tags.push(tag);
    index++;
}
line = line.replace(/word/g, 'letter');
for (var i = 0; i < tags.length; i++) {
    line = line.replace('$tag' + i + '$', tags[i]);
}
document.write('result ' + line)

This outputs: 输出:

result abc letter hey :$ my word $: letter :$ my word $:
^(.+?)?(:\$.+?\$:)(.+?)?$

正则表达式可视化

This will give you three capturing groups: 这将为您提供三个捕获组:

  1. Everything before :? 之前的一切:? and ?: ?:
  2. The content inbetween your custom tags 自定义标签之间的内容
  3. Everything after :? 之后的一切:? and ?: ?:

You then want to do an usual stringreplace on the first and third capturing group, replacing word with letter . 然后,您想在第一个和第三个捕获组上执行通常的stringreplace,将word替换为letter

The first and third group are optional, to :?word?: another word will match, too. 第一组和第三组对于:?word?: another word是可选的:?word?: another word也将匹配。

var regex = /^(.+?)?(:\$.+?\$:)(.+?)?$/i;
regex.exec('abc word hey :$ my word $:');  
alert(RegExp.$1.replace("word", "letter") + RegExp.$2 + RegExp.$3.replace("word", "letter"));

Fiddle 小提琴
Demo@debuggex 演示@ debuggex

There's no easy regular expression, I can think of. 我能想到的是,没有简单的正则表达式。

You can look for multiple regular expressions instead 您可以查找多个正则表达式

var s1 = 'abc word hey :$ my word $: def word :$ another word $: word ghi :$ a third word $: jkl word';
var s2;

// word at the beginning
s2 = s1.replace(/^([^:$]*)word/, '$1letter');
// word at the end
s2 = s1.replace(/word([^:$]*)$/, 'letter$1');
// and word in between
s2 = s1.replace(/(:[^$]*)word([^$]*:)/g, '$1letter$2');
console.log(s2);

See JSFiddle 参见JSFiddle

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM