【问题标题】:RegExp to ignore everything between <code> and <pre> tags正则表达式忽略 <code> 和 <pre> 标记之间的所有内容
【发布时间】:2014-02-17 18:52:28
【问题描述】:

试图解析一些内容(没有可用的 DOM - 或 DOM 解析器,即 jQuery、Cheerio)以用图像替换一些单词/符号(基本上是情感),但想忽略 &lt;code&gt;&lt;/code&gt; 和 @ 之间的所有内容987654325@ 这个例子非常适合替换所有的情绪,但不会忽略代码和前置标签 http://jsbin.com/odARehI/5/edit?js,console

如果你运行脚本,你会看到第一个打印在代码标签之前和第二个之后。

希望能看到另一组对该模式的关注。谢谢

// see link for a list of the emotions to parse
var pattern = /&gt;:\)|\([\w~]+\)|\\[:]?[od]\/|[:;\|bBiIxX8\(\)\]][=\-"^:]?[)>$&|\w\(\)*@#?]?[)>$&|\w\(\)*@#?]/g;

我尝试了一些没有弄乱原始匹配的方法。

对于 Don't-parse-html-with-regex-police-department:这是在服务器端运行,目前我没有 DOM 解析器的奢侈。

谢谢。

更新:对于忽略 &lt;code&gt; 标记的 RegExp 解决方案,请参阅这个简洁的解决方案,感谢 github/frissdiegurke in this commit

/(^|<\/code>)([^<]*|<(?!code>))*(<code>|$)/g

【问题讨论】:

  • 你能保证precode标签都不会嵌套在你的输入文本中吗?
  • @icktoofay 不是真的,好吧,在大多数情况下,如果是内联的,它要么只是一个 &lt;code&gt; code here &lt;/code&gt;,或者如果是一个代码块,它看起来像 &lt;pre&gt;&lt;code&gt; code here &lt;/code&gt;&lt;/pre&gt; - 但要回答你的问题,除了嵌套的 pre->code 之外,是的,没有嵌套。现在我想了想,忽略&lt;code&gt;&lt;/code&gt; 中的所有内容可能就足够了

标签: javascript regex nodebb


【解决方案1】:

如果没有 DOM 解析,您将遇到会失败的边缘情况。但是,这应该适合你。

鉴于此 HTML:

Hello :) <pre>Wassup :)</pre> Maybe :) <code>:) Foo</code> :) Bar

使用此代码:

var blocks = [];
html = html.replace(/(?:<pre>.*?<\/pre>|<code>.*?<\/code>)/g, function (match) {
    blocks.push( match );
    return '__BLOCK__';
});

html = html.replace(/:\)/g, 'SMILE');

html = html.replace(/__BLOCK__/g, function () {
    return blocks.shift();
});

产生:

Hello SMILE <pre>Wassup :)</pre> Maybe SMILE <code>:) Foo</code> SMILE Bar

只需调整 /:\)/g 替换即可工作,但您需要它。

【讨论】:

  • 如果__BLOCK__ 被动态选择为不出现在输入中的字符串,我会对此解决方案更满意。
  • 这是一个绝妙的答案。
【解决方案2】:

猜你正在使用 nodejs 或最近的 javascript 引擎(用于“map”和“split”实现),所以你可以这样做:

function replaceSpecial(str, pattern, replacement) {
  var REG = /(<code>.*?<\/code>)|(<pre>.*?<\/pre>)/i;
  return str.split(REG).map(function(s) {
    if ('' + s !== s)
      return '';
    if (s.match(REG))
      return s;
    return s.replace(pattern, replacement);
  }).join('');
}

例子:

replaceSpecial("hey :) <code>:)</code> :'( <pre> :'( :)</pre>", /(:\))|(:'\()/, function(s) {
  switch(s) {
    case ":)":
      return '<img src="smile.gif" />';
    case ":'(":
      return '<img src="cry.gif" />';
  }
})

将返回:

"hey <img src="smile.gif" /> <code>:)</code> <img src="cry.gif" /> <pre> :'( :)</pre>"

或者如果你只是想替换一个表情符号更简单:

replaceSpecial("hey :) <code>:)</code>", ":)", '<img src="smile.gif" />')

=>

"hey <img src="smile.gif" /> <code>:)</code>"

【讨论】:

  • 为了其他人不要重现我的错误:如果您想将分隔符保留在拆分数组中,示例中的括号很重要:)
【解决方案3】:
var co = -1, ce = 0, start=0, result; 
while ( ce != -1 ) {
   co = testString.indexOf('<code', ce);
   if (co > -1) {
     result += parse(testString.substring(start,co), pattern1); 
     start = co+1;
     ce = testString.indexOf('</code>', co + 5);
     if (ce >-1 ){
        start = ce + 7;
        ce = start;
        result += testString.substring(co,ce);
     }
  }
}
result += parse(testString.substring(start), pattern1);

console.log(结果);

【讨论】:

  • 做了一些快速的performance testing 并且这个功能变成了最快的,而不是太多。因此,将此标记为已接受的答案。谢谢
猜你喜欢
  • 2022-07-29
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
相关资源
最近更新 更多