从文件中的字符索引获取行号

时间:2015-03-07 10:00:24

标签: javascript regex string coffeescript

我有一个由单词组成的字符串输入。我使用regex.exec(g)来获取函数getWord(input)

的所有单词

所以我的输入可能如下所示: word word2 someword blah

我从exec得到的是包含index匹配的对象。所以它是这样的数组: [ 'word', index: 0, input: "..."] ... [ 'someword', index: 11, input: "..."] ...

我需要的是轻松计算这个单词" someword"在第2行使用索引(11)(因为我没有任何其他值告诉我行数是多少)

以下是我提出的问题:匹配' \ n'直到匹配\ n与更高的索引然后是单词索引。不确定这在10k行文件中是否有问题。

想法的片段:

getLineFromIndex: (index, input) ->
  regex = /\n/g
  line = 1

  loop
    match = regex.exec(input)
    break if not match? or match.index > index

    line++

  return line

有点大优化可以在这里完成。我可以保存正则表达式和最后一个匹配,所以每次我想检查行号时,我都不会迭代所有输入。只有当最后一个匹配的索引低于当前索引时才会执行正则表达式。

这是优化的最终想法:

  ###
    @variable content [String] is input content
  ###
  getLineFromIndex: (index) ->
    @lineMatcher = @lineMatcher || /\n/g
    @lastLine = @lastLine || 1

    if @eof isnt true
      @lastMatch = @lastMatch || @lineMatcher.exec(@content)

    if @eof or index < @lastMatch.index
      return @lastLine
    else
      match = @lineMatcher.exec(@content)
      if not @eof and match is null
        @eof = true
      else
        @lastMatch = match

      @lastLine++

    return @lastLine

2 个答案:

答案 0 :(得分:0)

您的伪代码似乎可以完成这项工作。 但我看不出你如何通过搜索词的偏移来推断行号。 我会按行分割输入文本,然后在数组中查找搜索到的单词,如果找到则返回行索引。

var input= "word word2 \n"+
           "someword blah";


function getLinesNumberOf( input, word){
  var line_numbers=[];
  input.split("\n").forEach(function(line, index){
    if( line.indexOf(word)>=0 ) line_numbers.push(index);
  });
  return line_numbers;
}


console.log(getLinesNumberOf(input,"someword"));

我已添加对搜索到的单词的多次出现的支持。

修改

为了避免使用大输入过多的内存消耗,您可以按顺序解析(for the same avantanges of SAX vs DOM):

function getLinesNumberOf( word, input ){

    input+= "\n";//make sure to not miss the last line;

    var line_numbers=[], current_line=0;
    var startline_offset=0;

    do{
        //get the offset next of the next breakline 
        endline_offset= input.indexOf("\n",startline_offset);

        //get the offset of the searched word in the line 
        word_offset= input.substring(startline_offset,endline_offset).indexOf(word, 0);

        //check if the searched word has been found and if it has been found on current_line
        if( word_offset >= 0 && word_offset < endline_offset ) {
            //if true the current_line is stored
            line_numbers.push(current_line);
        }

        //the offset of the next line is just after the breakline offset  
        startline_offset= endline_offset+1;

        current_line++;

    }while(endline_offset>=0);//we continue while a breakline is found

    console.log(line_numbers);
}

答案 1 :(得分:0)

  1. 剪切输入(a.substr(0,11))。
  2. 拆分它(a.substr(0,11).split(&#39; \ n&#39;))。
  3. 统计它(a.substr(0,11).split(&#39; \ n&#39;)。长度)。