【问题标题】:JavaScript regex to find special words not wrapped in a tagJavaScript 正则表达式查找未包含在标签中的特殊单词
【发布时间】:2013-08-29 14:18:52
【问题描述】:

我正在尝试编写一个正则表达式来搜索字符串并查找包含在大括号中的单词,这些单词未包含在具有特定属性(数据占位符)的 span 标签中。

示例文本:

This is a test. Testing <span class="anything">{variable}</span> wrapped without the attribute, but this one <span data-placeholder="val">{variable}</span> is. The first should match, the second should not, and the last one should as well {variable}

到目前为止,我想出的最好的是:

/[^>]{(.)*}[^>]/g

但这有一些问题。结束 } 之后可能有也可能没有文本,因此该模式与示例文本中的最后一个实例不匹配。它也不会匹配第一个实例,我不确定如何为正则表达式的第一部分编写“匹配除此单词之外的任何内容”。

目标是转换以下实例(注意任何东西都是文字):

{variable}
<span class="anything">{variable}</span>

到这个(或):

<span data-placeholder="">{variable}</span>
<span data-placeholder="" class="anything">{variable}</span>

不会中断任何已转换的现有实例。

谢谢!

编辑:使用 DOM 遍历和文本节点的正则表达式组合解决。谢谢@jonathan-m 和@frankiethekneeman!

【问题讨论】:

  • 谷歌“负前瞻”
  • 正则表达式解析html非常不可靠。最佳实践:不要这样做。而是使用 HTML 解析器,然后检查标签的内容。正则表达式对于内容是可靠的。
  • 您真的应该诚实地使用带有 HTML 解析器的递归方法。不仅因为“以 cthulu 方式解析 HTML”,还因为它会使您的代码更具可扩展性,并且更易于维护。你在使用任何 Javascript 框架吗?这是服务器端代码,还是要在某个页面上执行?
  • 您尝试查询的这些 HTML 文档是否有效?
  • 如果您解决了它并认为您的解决方案可能对其他人有帮助,请将其作为答案发布。

标签: javascript regex


【解决方案1】:

我的解决方案(再次感谢 @jonathan-m 和 @frankiethekneeman):

//remove any broken variables
variables = $( 'span[data-placeholder]', this.editor );
for ( i = 0, len = variables.length; i < len; i++ ) {
    if ( pp.arrayIndexOf( dict, variables[ i ].innerHTML ) == -1 ) {
        t = variables[ i ].childNodes[ 0 ];
        $( t ).unwrap( );
    }
}

//convert any variables already in a span tag
variables = $( 'span', this.editor );
for ( i = 0, len = variables.length; i < len; i++ ) {
    t = variables[ i ].innerHTML.match( /^{(.)*}$/ );

    if ( !variables[ i ].hasAttribute( 'data-placeholder' ) && t != null && pp.arrayIndexOf( dict, t[ 0 ] ) != -1 ) {
        variables[ i ].setAttribute( 'data-placeholder', this.getVariable( t[ 0 ] ) );
    }
}

//convert any variables in a text node
variables = $( 'p', this.editor );
for ( i = 0, len = variables.length; i < len; i++ ) {
    for ( j = 0, len2 = variables[ i ].childNodes.length; j < len2; j++ ) {
        if ( variables[ i ].childNodes[ j ].nodeType == 3 ) {
            t = variables[ i ].childNodes[ j ].data.match( /{(.)*}/ );

            if ( t != null && pp.arrayIndexOf( dict, t[ 0 ] ) != -1 ) {
                span = document.createElement( 'span' );
                span.setAttribute( 'data-placeholder', this.getVariable( t[ 0 ] ) );
                span.innerHTML = t[ 0 ];

                variables[ i ].replaceChild( span, variables[ i ].childNodes[ j ] );
            }
        }
    }
}

循环 1:如果用户编辑了文本并将变量转换为其他内容,则将编辑后的内容从其包装中取出。

循环2:检查每个span标签,如果它已经有数据占位符忽略它,如果没有检查它的内容,看看它是否是一个变量。

循环 3:检查每个 p 标签,在其中查找与变量匹配的文本节点。如果找到,创建一个 span 并用包装器替换文本节点。

注意:刚刚意识到我没有在一个文本节点中测试过多次出现,所以这可能不适用于此代码。现在去测试。

【讨论】:

  • 你的正则表达式不好,试试我的:" here is a {variable} and a mustache } ".match( /{(.)*}/ )["{variable} and a mustache }", " "]" here is a {variable} and a mustache } ".match( /{[^}]+}/g )["{variable}"]
  • 是的,我原来的正则表达式匹配太多了,我现在正在使用 /{([^}]+)}/g。谢谢!
【解决方案2】:

直接在我的谷歌浏览器中处理这个问题,我发现以下代码在 JavaScript 控制台中是一个有希望的开始:

代码

nodeList = document.querySelectorAll('span');
nodeArray=[];
for (i=0; i < nodeList.length; i++) {nodeArray.push(nodeList[i]);}
nodeArray.filter(function(node) {return node.innerText.match(/{variable}/)});

请注意我们如何根据文档对象模型选择实际的 HTML 元素,然后根据其文本内容寻找候选者。或者,可以使用 .innerHTML,或者通过分配给这些属性来实际操作文档内容。

结果

[
<span class=​"str">​
"/span> wrapped without the attribute, but this one <span data-placeholder="val">{variable}</"
</span>​
, 
<span class=​"pln">​{variable}​</span>​
, 
<span class=​"pln">​{variable}​</span>​
, 
<span class=​"comcopy">​
"@Jonathan What are the {variable} and the <span...> following it contained in? Are they in another span, div, p, or body tag? if yes, which?"
</span>​
, 
<span class=​"str">​/{variable}/​</span>​
]

jQuery.contains 也可能很有趣。

【讨论】:

    猜你喜欢
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 2018-10-10
    相关资源
    最近更新 更多