向后搜索:在JavaScript中实现string.lastIndexOf(/ REGEX /,offset)

时间:2016-08-13 19:49:48

标签: javascript regex search

我的总体目标是在点击网页后选择整个单词。

为此,我需要找到当前选择开头之前的第一个单词边界。感谢@4castle,我有一个正则表达式,正确识别单词边界。我目前的目标是使用此正则表达式向后搜索字符串,模仿stringHaystack.lastIndexOf(stringNeedle, offset)的工作方式。

我目前的解决方案是在offset点之前反转字符串的一部分,然后使用reverseString.search(regex),如下所示:

function searchBackwards (string, offset, regex) {
  string = string.substring(0, offset)
  var reverseString = ""
  var ii = string.length
  var backSet

  while (ii--) {
    reverseString += string[ii]
  }

  backSet = reverseString.search(regex)
  offset = backSet < 0 ? 0 : offset - backSet
  return offset
}

然而,我觉得必须有一个更优雅的解决方案。您对改进这种方法有什么建议吗?

编辑:按照@WiktorStribiżew的建议,我已将searchBackwards功能更改为:

function searchBackwards(string, offset, regex) {
  var adjust = 0
  var result
  string = string.substring(0, offset)

  while (result = regex.exec(string)) {
    offset = result.index
    adjust = result[0].length
  }

  return adjust ? offset + adjust : 0
}

在我对Chrome的测试中,它的速度是我原来的两倍。

可测试示例:https://jsfiddle.net/77np9gp9/

工作代码:

var selection = window.getSelection()
document.body.onmouseup = selectWholeWords

function selectWholeWords() {
  if (selection.rangeCount) {
    var range = selection.getRangeAt(0)
    // RegExp to detect word boundaries but to allow ' and - in
    // the middle of words
    // ^['-]                    - match a single-quote or a hyphen
    //                            at the beginning
    // [\s!-/:-@\[-`\{-~'-]{2,} - match a whole range of non-word
    //                            characters pairs possibly 
    //                            including a ' or a -
    // [\s!-/:-@\[-`\{-~]       - match a whole range of non-word
    //                            characters on their own
    var regex = /^['-]|[\s!-/:-@\[-`\{-~'-]{2,}|[\s!-/:-@\[-`\{-~]/

    var container = range.startContainer
    var string = container.textContent 
    var offset = searchBackwards(string, range.startOffset)
    range.setStart(container, offset)     

    container = range.endContainer
    string = container.textContent
    offset = range.endOffset
    offset += string.substring(offset).search(regex)
    if (offset < 0) {
      offset = string.length
    }
    range.setEnd(container, offset)

    selection.removeAllRanges()
    selection.addRange(range)
  }

  function searchBackwards (string, offset) {
    string = string.substring(0, offset)
    var reverseString = ""
    var ii = string.length
    var backSet

    while (ii--) {
      reverseString += string[ii]
    }

    backSet = reverseString.search(regex)
    offset = backSet < 0 ? 0 : offset - backSet
    return offset
  }
}

0 个答案:

没有答案