如何替换字符串而不会丢失已对内容可编辑div中的部分文本执行的文本格式

时间:2013-12-29 05:09:03

标签: javascript jquery regex

我有一个div,其conenteditble属性设置为true。

假设用户输入了类似

的内容

:lazy 棕色狐狸跳过超过超级:懒狗

现在,我想在句子中出现第二个“:lazy”。这是动态的。句子可以包含任意数量的“:lazy”(或“任何单词”,必须用“some text”替换),只需要替换一个。必须这样做而不会丢失已对句子进行的文本格式 这是我试过的。这将始终取代该单词的第一次出现。

<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<script>
      $(document).ready(function(){
      $("#rewrite").click(function(){
      var regex=/\.*[:]\S*/
      var originalHtml = $('#editableDiv').html();
      var newHtml = originalHtml.replace(regex,"sleeping");
      $('#editableDiv').html(newHtml);
      });
    });
</script>
</head>
<body>
<form name="myform">
<div id="editableDiv"  contenteditable="true">
    the quick <b><i>:lazy</i></b> <b><i>brown</i></b> fox jumps over a <b><i>:lazy<span style="color:red;"> dog </span></i></b>dog
</div>
<input type="button" id="rewrite" value="Rewrite">
</form>
</body>
</html> 

1 个答案:

答案 0 :(得分:1)

假设正则表达式变量设置如下:

//                               v - make the search global
var regex = /\.*[:]\w+(?!\w*[;])/g
//Only word letters ^^ ^- negative look-ahead; make sure that the characters
//one or more matches|    do not have a semi-colon following them(like inline
//                        css styles).

不应修改任何周围的标签。当然,我没有给出所有的测试用例,因为我想不到很多,但它与我给它的内容有效here

正如您可能已经知道的那样,正则表达式中的\S字符是一个否定的空格字符,这意味着它很像点(。),因为它几乎可以匹配任何字符。这包括括号(<>),它会使它与html匹配,从而打破你的html字符串。

修改

由于javascript没有负面的后卫,我想出的答案是一种黑客攻击,在我看来......但是它有效且可配置:

将您的调用替换为替换方法:

var regex = /\.*([:]\w+(?!\w*[;]))/g;//A change here to make it match group
var originalHtml = $('#editableDiv').html(); // Didn't change anything here, just
                                             // included it to not break anything
var mi = 1; //match index
var newHtml = originalHtml.replace(regex, function() {
    var ret = (mi == 2)?'sleeping':arguments[0];
    //         boolean   if true    if false
    // The above is a ternary operator in case you weren't aware.  arguments is
    // an array composed of all arguments sent to the anonymous function, with
    // the first being the match, then the match groups, then the position in
    // the string in which is is found, and finally the full string it was
    // matched against.

    // The above if/then/else operator checks if the match index(mi) is equal to
    // the position of 2, if it is, then return 'sleeping', if not, return the 
    // match word

    mi++; //increase match index by one, every time function is ran
          //as it is ran each time there is a grouped match
    return ret; //return return variable
});

这是展示上述情况的demo