【问题标题】:Regex - Get all text between > and <, however don't get text if its between > </正则表达式 - 获取 > 和 < 之间的所有文本,但如果介于 > </ 之间则不获取文本
【发布时间】:2020-11-27 06:49:22
【问题描述】:

我在试图找出这个正则表达式代码时遇到问题。让我展示一下代码,然后再解释一下。

<div class="test">
    Nisl rhoncus mattis rhoncus urna neque viverra. Senectus et netus et
    malesuada.
    <button class="button">Feugiat nisl pretium fusce id velit.</button>
    Turpis nunc eget lorem dolor sed viverra ipsum nunc. Gravida dictum
    fusce ut placerat. Viverra maecenas accumsan lacus vel facilisis.
 </div>

所以我试图让正则表达式介于 > 和 <button class="button">Feugiat nisl pretium fusce id velit.</button>

所以正则表达式应该解析这个并只返回这些行:

Nisl rhoncus mattis rhoncus urna neque viverra。 Senectus et netus et malesuada。

Turpis nunc eget lorem dolor sed viverra ipsum nunc。 Gravida dictum fusce ut placerat。 Viverra maecenas accumsan lacus vel facilisis。

还因为它将用于解析 HTML,我需要它来忽略完全空白的空间。我的意思是

   </div>
</div>

从技术上讲,两者之间的空格是有效的,但我不想捕获空格,除非包含文本而不仅仅是空格。想象一下在 HTML 之间获取段落。这个想法是获取 divs 之间的所有文本,然后用 &lt;p&gt; 包裹它,但是某些情况下,例如按钮,里面不应该有 &lt;p&gt;

我不确定这是否可能。我希望这是有道理的,任何帮助都将不胜感激!

编辑:

使用 NodeJS

我正在尝试将 MD 文件(Github 降价文件)解析为 HTML,并在自定义语法之间有一个中间步骤,如下所示:

[flipcard]
[front color:blue]
Morbi tristique senectus et netus et malesuada. Interdum consectetur libero id faucibus nisl tincidunt. Purus faucibus ornare suspendisse sed nisi. Laoreet id donec ultrices tincidunt arcu. Elementum pulvinar etiam non quam lacus suspendisse faucibus.
[/front]
[back]
Nisl rhoncus mattis rhoncus urna neque viverra. Senectus et netus et malesuada.
[button]Feugiat nisl pretium fusce id velit.[/button] Turpis nunc eget lorem dolor sed viverra ipsum nunc. Gravida dictum fusce ut placerat. Viverra maecenas accumsan lacus vel facilisis. Nascetur ridiculus mus mauris vitae ultricies leo integer. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus. Velit laoreet id donec ultrices.[/back] 
[/flipcard]

它几乎就像自定义 HTML,但在 markdown 文件中,然后将使用我的自定义解析器转换为这个,一旦我的解析器完成,我通过 NodeJS Marked 解析器运行它以捕获剩余的 markdown 元素。然后我得到这个:

 <div class="flipcard">
      <div class="front" style="color: blue">
        Morbi tristique senectus et netus et malesuada. Interdum consectetur
        libero id faucibus nisl tincidunt. Purus faucibus ornare suspendisse sed
        nisi. Laoreet id donec ultrices tincidunt arcu. Elementum pulvinar etiam
        non quam lacus suspendisse faucibus.
      </div>
      <div class="back">
        Nisl rhoncus mattis rhoncus urna neque viverra. Senectus et netus et
        malesuada.
        <button class="button">Feugiat nisl pretium fusce id velit.</button>
        Turpis nunc eget lorem dolor sed viverra ipsum nunc. Gravida dictum
        fusce ut placerat. Viverra maecenas accumsan lacus vel facilisis.
        Nascetur ridiculus mus mauris vitae ultricies leo integer. Pellentesque
        pulvinar pellentesque habitant morbi tristique senectus et netus. Velit
        laoreet id donec ultrices.
      </div>
    </div>

这非常接近我的需要,但我需要最终输出是这样的:

<div class="flipcard">
      <div class="front" style="color: blue">
        <p>
          Morbi tristique senectus et netus et malesuada. Interdum consectetur
          libero id faucibus nisl tincidunt. Purus faucibus ornare suspendisse
          sed nisi. Laoreet id donec ultrices tincidunt arcu. Elementum pulvinar
          etiam non quam lacus suspendisse faucibus.
        </p>
      </div>
      <div class="back">
        <p>
          Nisl rhoncus mattis rhoncus urna neque viverra. Senectus et netus et
          malesuada.
        </p>
        <button class="button">Feugiat nisl pretium fusce id velit.</button>
        <p>
          Turpis nunc eget lorem dolor sed viverra ipsum nunc. Gravida dictum
          fusce ut placerat. Viverra maecenas accumsan lacus vel facilisis.
          Nascetur ridiculus mus mauris vitae ultricies leo integer.
          Pellentesque pulvinar pellentesque habitant morbi tristique senectus
          et netus. Velit laoreet id donec ultrices.
        </p>
      </div>
    </div>

【问题讨论】:

  • 不要使用正则表达式解析 HTML。正则表达式是我们根本无法解析 HTML。使用 HTML 解析器。
  • 您对 html 解析器有什么建议吗?我为 NodeJS 尝试了 html-parser,但它没有用。我这样做的原因是我在 MD 文件中有自定义内容,例如 [front] [/front]。所以我运行我的自定义解析器来获取所有这些元素而不是 MD 解析器到 HTML,但是 p 标签不太正确,需要在上面的特定位置删除和重新添加。
  • 这是问题中需要的所有有价值的信息:您正在使用节点,您已经尝试过解析器,哪个,您尝试了什么代码,什么“不起作用”表示,什么是“MD”文件,以及这些文件的示例,所需输出的示例。
  • 谢谢。我用所有信息更新了它,最终输出需要什么以及我为什么要尝试以这种方式实现这一目标。
  • 好的,所以你几乎用解析器解决了所有问题,你只需要在 div.flipcard &gt; d 的文本中换行 &lt;p&gt;?

标签: javascript html node.js regex


【解决方案1】:

据我了解,您有这样的解析器生成的 HTML:

var htmlFragment = `<div class="flipcard">
  <div class="front" style="color: blue">
    Morbi tristique senectus et netus et malesuada. Interdum consectetur
    libero id faucibus nisl tincidunt. Purus faucibus ornare suspendisse sed
    nisi. Laoreet id donec ultrices tincidunt arcu. Elementum pulvinar etiam
    non quam lacus suspendisse faucibus.
  </div>
  <div class="back">
    Nisl rhoncus mattis rhoncus urna neque viverra. Senectus et netus et
    malesuada.
    <button class="button">Feugiat nisl pretium fusce id velit.</button>
    Turpis nunc eget lorem dolor sed viverra ipsum nunc. Gravida dictum
    fusce ut placerat. Viverra maecenas accumsan lacus vel facilisis.
    Nascetur ridiculus mus mauris vitae ultricies leo integer. Pellentesque
    pulvinar pellentesque habitant morbi tristique senectus et netus. Velit
    laoreet id donec ultrices.
  </div>
</div>`;

并且您想将div.flipcard &gt; div 的每个“裸”文本节点子节点包装在其自己的&lt;p&gt; 中。

如果您熟悉 jQuery,那么这是一个简单的操作。选择目标节点,调用.wrap('&lt;p&gt;')Cheerio 是 node 中的 jQuery 等价物,所以如果你想要同样的便利,你可以拥有它:

const cheerio = require('cheerio');

$doc = cheerio.load('<div>' + htmlFragment + '</div>');

$doc.find('div.flipcard > div').contents().filter(function () {
    return this.nodeType === this.TEXT_NODE;
}).wrap("<p>");

console.log($doc.html());

打印这个:

<div class="flipcard">
  <div class="front" style="color: blue"><p>
    Morbi tristique senectus et netus et malesuada. Interdum consectetur
    libero id faucibus nisl tincidunt. Purus faucibus ornare suspendisse sed
    nisi. Laoreet id donec ultrices tincidunt arcu. Elementum pulvinar etiam
    non quam lacus suspendisse faucibus.
  </p></div>
  <div class="back"><p>
    Nisl rhoncus mattis rhoncus urna neque viverra. Senectus et netus et
    malesuada.
    </p><button class="button">Feugiat nisl pretium fusce id velit.</button><p>
    Turpis nunc eget lorem dolor sed viverra ipsum nunc. Gravida dictum
    fusce ut placerat. Viverra maecenas accumsan lacus vel facilisis.
    Nascetur ridiculus mus mauris vitae ultricies leo integer. Pellentesque
    pulvinar pellentesque habitant morbi tristique senectus et netus. Velit
    laoreet id donec ultrices.
  </p></div>
</div>

当然,您可以使用诸如jsdom 之类的常规 DOM 解析器来做同样的事情,只需稍微多做一些工作即可:

document.querySelectorAll('div.flipcard > div').forEach(div => {
    for (let i = div.childNodes.length - 1; i >= 0; i--) {  // work from the end so we don't mess up the index
        let child = div.childNodes[i];
        if (child.nodeType == child.TEXT_NODE) {            // if we're at a text node
            let p = document.createElement('P');            // create `<p>`
            div.insertBefore(p, child.nextSibling);         // append that after the text node
            p.appendChild(child);                           // move the text node into the `<p>`
        }
    }
});

【讨论】:

  • 我需要对此进行更多研究,但这样的事情是否适用于许多不同的情况。 Flipcard 只是一种情况,如果假设还有另一种称为 Flipcard2 的情况。或者如果 div 有 5 层深。我对正则表达式的想法是它会捕获所有这些情况。或者由于某种原因,在翻转卡片之后留下了一些文本,它是 &lt;/div&gt; left over text &lt;/body&gt; 使用 Markdown 文件人们会做一些愚蠢的事情,我需要捕捉错误以将任何剩余的文本包装在 &lt;p&gt; 标签中
  • @Zodsmar 忘记正则表达式。正则表达式无法处理 HTML,这是现实。是的,这可以适用于您希望实施的任何情况,使用 Cheerio,编写一个非常灵活的解决方案甚至不难。
  • 我会考虑以这种方式解决它。我唯一想理解的是文本是我使用 > 或 ] 的文本。解析 [front] 一些文本 [/front] 或 &lt;div&gt; &lt;/div&gt; 之间有什么区别我的第一部分解析翻转卡并将其转换为 HTML 都是通过正则表达式完成的。
  • @Zodsmar 好吧,它不应该,但你可以侥幸逃脱。正则表达式不擅长 anything 嵌套,这与方括号与尖括号无关。 “将[bla]转换为&lt;div class="bla"&gt;“在这个嵌套的HTML节点树中找到所有文本节点子节点,并将它们转换为&lt;p&gt;简单得多。我>。这就是为什么你在第一种情况下逃脱了正则表达式,但在第二种情况下却不行。
  • @Zodsmar 假设实际的人编写了 [flipcard] 标记,然后将其转换为粗略的 HTML(通过正则表达式,就像您目前所做的那样,没有问题),并将结果放入 HMTL 解析器是不错的策略。当人们编写标记代码时,HTML 解析器将解决错误的嵌套和所有其他可能出错的事情,并且它允许您轻松微调结果(并且不会因为您的正则表达式慢慢失控而拉扯头发但只是发现它仍然不能正常工作,而且永远不会)。
猜你喜欢
  • 1970-01-01
  • 2011-03-18
  • 2020-03-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 2012-03-13
  • 2019-01-20
  • 2017-06-16
相关资源
最近更新 更多