如何从<p>标签中提取<ul>(使用jQuery)?

时间:2015-08-07 14:19:27

标签: javascript jquery html

我正在玩一些有意思的div,过了一段时间我得到了以下代码:

<p>
some text
<ul>
  <li>A</li>
  <li>2</li>
</ul>
another text
</p>

现在我想获得有效的HTML。因此,我必须从ul中提取p,或者换句话说,在p之前关闭ul标记,然后在ul之后再次打开它。之后我的代码应该是这样的:

<p>some text</p>
<ul>
  <li>A</li>
  <li>2</li>
</ul>
<p>another text</p>

我如何实现这一点(使用jQuery)?

我已经尝试了这个(其中elem是包含p的jQuery元素):

var reg1 = new RegExp('<ul>', 'g');
var reg2 = new RegExp('</ul>', 'g')
elem.html(elem.html().replace(reg1, '</p><ul>').replace(reg2, '</ul><p>'));

这似乎有效。但我不确定这是否是最佳解决方案。 你有更好的主意吗?

3 个答案:

答案 0 :(得分:2)

您正在寻找before / after

请勿使用此注册表。

Regex适用于需要针对特定​​文本集进行定位的特殊情况,其目的是在jQuery / Javascript中可以避免大部分时间。

如果你这样做

var ul = $('p').find('ul');
ul.closest('p').before(ul);

$(document).on('ready', function(){
  
    var ul = $('div').find('ul');

    ul.closest('div').addClass('red').before(ul);
});
.red{
  color: red;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>
  <span>some text</span>
  <ul>
    <li>List</li>
  </ul>
  <span>and more text</span>
</div>

请注意,在ul标记内使用olp标记是违法的。因此,我将p更改为div以进行演示。如果您使用此代码p而不是div,大多数浏览器都不会搞砸。

请参阅Should ol/ul be inside <p> or outside?

答案 1 :(得分:2)

发生了什么

浏览器将无效的HTML解析为有效的DOM,可能在必要时添加结束标记。在Chrome中我看到:

<p>
  before
  <ul>
    <li>item></li>
  </ul>
  after
</p>

在DOM检查器中显示为

<p>
  before
</p>
<ul>
  <li>item></li>
</ul>
after
<p></p>

解决方案

因此,假设您在字符串中的某处具有未解析的 HTML,则可以使用以下(已修改的)正则表达式来实现更紧密的匹配。但这可能有点矫枉过正。

var beginRegex = new RegExp(/<p>(((?!<\/p>).|[\r\n])*?)<ul>/gi);
var endRegex = new RegExp(/<\/ul>(((?!<p>).|[\r\n])*?)<\/p>/gi);

var content = ...;

$('#target')
    .html(content
        .replace(beginRegex, '<p>$1</p><ul>')
        .replace(endRegex, '</ul><p>$1</p>')
    );

JSFiddle

它仅匹配<p>之前未关闭的<ul>标记,之后也匹配。在不使用复杂的正则表达式的情况下,可以使用的一件事是对不区分大小写的使用i修饰符,因为HTML不区分大小写。

答案 2 :(得分:0)

感谢Shadowen我终于接受了他的建议并对其进行了一些修改以获得我需要的东西。我忘记在我的原始问题中提出的问题 - 这应该适用于列表,也适用于列表。所以这是适合我的解决方案:

var content = '...';
var beginRegexUl = new RegExp(/<p>(((?!<\/p>).|[\r\n])*?)<ul>/gi);
var endRegexUl = new RegExp(/<\/ul>(((?!<p>).|[\r\n])*?)<\/p>/gi);
var beginRegexOl = new RegExp(/<p>(((?!<\/p>).|[\r\n])*?)<ol>/gi);
var endRegexOl = new RegExp(/<\/ol>(((?!<p>).|[\r\n])*?)<\/p>/gi);

$('#target')
  .html(content
    .replace(beginRegexUl, '<p>$1</p><ul>')
    .replace(endRegexUl, '</ul><p>$1</p>')
    .replace(beginRegexOl, '<p>$1</p><ol>')
    .replace(endRegexOl, '</ol><p>$1</p>'));

JSFiddle