2014-11-20 103 views
0

我有一个像Emmet/ZenCoding一样工作的小型jQuery脚本,并将关键字扩展为textarea中的TAB键的片段。替换随机单词的最后一次出现

当关键字只有一个出现时,它工作正常,但我不知道如何替换字符串中单词的最后一次出现。

下面是一个例子的字符串,将在textarea键入:

Have a look at the rules : rules 

在这种情况下,用户将第二规则后按TAB键,并且脚本以阵列取出相应的值,用一个实际的规则链接代替这个词。它应该(理论上)本所取代:

Have a look at the rules : http://website.com/rules.php 

我的问题是,我使用replace,它会取代这个词,这是不期望的行为的所有出现次数。下面是脚本的相关部分:

var content = $(this).val(); 
content = content.replace(lastWord, insertSnippets[lastWord]); 
$(this).val(content); 

它首先获取在当时textarea的内容,替换相应的值的字(规则)(实际的链接)。有没有什么方法可以取代最后的发生?它并不总是“规则”这个词,还有其他十几个长度不明的关键字。

TL; DR如何仅用jQuery/Javascript替换单词的最后一次出现?

我正在考虑得到目前的插入符号的位置,并且只替换它的左边的单词,但获得插入符号的位置似乎相当单调乏味 - 我仍然不知道如何进行替换。

回答

0

使用正则表达式,只匹配内容字符串的末尾。

/yourWord$/ 

将匹配yourWord,如果它是一个字符串

+0

谢谢你的快速回复,我取代了我的代码的最后字VAR与你贴什么,但现在当我按下'TAB'键也不会再扩大。 – Drown 2014-11-20 19:56:28

0

的尽头仅仅调整了正则表达式位:

var content = $(this).val(); 
content = content.replace(lastWord+'.*?$', insertSnippets[lastWord]); 
$(this).val(content); 
+0

我试过你的代码,它不会再扩展了,我必须做任何事情来将lastWord'var'连接到正则表达式中吗? – Drown 2014-11-20 19:53:44

+0

@Drown yes whoops – 2014-11-20 19:56:10

+0

它仍然无法工作,我在“content”,“lastWord”和“insertSnippets [lastWord”上做了一些'console.log',并且我有所有期望的值。它根本不被替换。 :( – Drown 2014-11-20 20:01:27

1

这可能做到这一点,只要你的搜索字符串没有按不包括任何正则表达式特殊字符:

var replaceLast = function(searchFor, replaceWith, str) { 
    return str.replace(
     new RegExp("^(.*)" + searchFor + "(.*?)$"), 
     function(_, before, after) {return before + replaceWith + after;} 
    ); 
}; 

replaceLast("rules", "http://website.com/rules.php", 
      "Have a look at the rules : rules", "rules"); 
//=> "Have a look at the rules : http://website.com/rules.php" 

如果将此函数传递给某个curry功能,那么你可以通过

var updateRules = replaceLast("rules", "http://website.com/rules.php"); 
// ... later 
updateRules("Have a look at the rules : rules", "rules"); 
//=> "Have a look at the rules : http://website.com/rules.php" 

创建诸如updateRules功能,但原有的功能可能是你所需要的。

+0

这工作得很好,现在唯一的问题是,我只能在'textarea'中替换一个单词,虽然这可能是因为我处理所有这些,我会做一些更多的尝试和尝试排序。非常感谢你的时间。 – Drown 2014-11-20 20:15:29

1

下面是我使用contenteditable字段创建的(仅测试webkit)。

它做了几件事情很好,虽然可能效率低下:

  • 替换与生活在一个对象相关片段的字
  • 仅替换当前单词的插入符号是
  • 设置你的光标到标签结束后要完成

尝试输入“等等等等规则”,并在“规则”之后点击标签。尝试在字符串中使用多个“规则”。

var content = document.getElementById('content') 
 

 
content.addEventListener('keydown', function (event) { 
 

 
    var _this  = this, 
 
     text  = this.innerHTML; 
 

 
    if (event.keyCode == 9) { 
 
     event.preventDefault() 
 

 
     var sel   = window.getSelection(), 
 
      currentWord = getWord(), 
 
      val   = sel.anchorNode.nodeValue, 
 
      snippet  = tabComplete(currentWord), 
 
      range  = sel.getRangeAt(0) 
 

 
     var selArray = sel.anchorNode.nodeValue.split(' ') 
 

 
     if (snippet !== undefined) { 
 
      var currentWordPosition = [ (range.endOffset - currentWord.length), range.endOffset ] 
 

 
      var newText = text.splice(currentWordPosition[0], currentWordPosition[1], ' '+snippet) 
 

 
      _this.innerHTML = newText; 
 

 
      sel.collapse(_this.firstChild, sel.anchorNode.nodeValue.length) 
 
     } 
 
    } 
 
    
 
}) 
 

 
var snippets = { 
 
    'rules' : 'http://website.com/rules.php', 
 
    'faq' : 'http://website.com/faq.php' 
 
} 
 

 
function tabComplete(string) { 
 

 
    if (typeof string !== 'string') { return false; } 
 

 
    var snippetKeys = Object.keys(snippets) 
 

 
    for (var i=0; i<snippetKeys.length; i++) { 
 
     if (snippets[string]) { 
 
      return snippets[string] 
 
     } 
 
    } 
 
} 
 

 
function getWord() { 
 
    var range = window.getSelection().getRangeAt(0); 
 
    if (range.collapsed) { 
 
     text = range.startContainer.textContent.substring(0, range.startOffset+1); 
 
     return text.split(/\b/g).pop(); 
 
    } 
 
    return ''; 
 
} 
 

 
String.prototype.splice = function(start, length, replacement) { 
 
    return this.substr(0,start)+replacement+this.substr(start+length); 
 
}
#content { 
 
    width:350px; 
 
    height:150px; 
 
    background-color: #333; 
 
    color: white; 
 
    font-family: sans-serif; 
 
    padding:10px; 
 
}
<div id="content" contenteditable></div>

+0

这正是我正在寻找的,非常感谢您的答案。但是,有没有办法使这个工作与'textarea' ?我无法控制我使用该脚本的网站的源代码 - 这是一个Chrome扩展。 – Drown 2014-11-21 01:24:36

相关问题