JS / node.js中匹配字符的行号

时间:2011-08-04 18:13:15

标签: javascript regex node.js

是否可以在Javascript或node.js中找到多行输入(例如文件)的正则表达式匹配字符的行号?

6 个答案:

答案 0 :(得分:6)

是的,有一个半尴尬的工作。

http://jsfiddle.net/tylermwashburn/rbbqn/

var string = "This\nstring\nhas\nmultiple\nlines.",
    astring = string.split('\n'),
    match = /has/, foundon;

Array.each(astring, function (line, number) {
    if (match.exec(line))
        foundon = number + 1;
});

答案 1 :(得分:3)

使用解析器生成器可能是个好主意。 Zach Carter的jison报告了行号。这是一个小实用程序的示例,它使用jison来解析JSON并使用行号报告错误。这可能是一个很好的起点。

https://github.com/zaach/jsonlint

对于最小的解决方案,我可能尝试使用exec方法(/myregex/.exec(mystring).index)从正则表达式获取索引,获取子字符串(mystring.substring(0, index)),将其拆分为换行符,并计算数量数组中的元素。

答案 2 :(得分:2)

如何通过字符串索引获取行号

function lineNumberByIndex(index,string){
    // RegExp
    var line = 0,
        match,
        re = /(^)[\S\s]/gm;
    while (match = re.exec(string)) {
        if(match.index > index)
            break;
        line++;
    }
    return line;
}

这是多么有用

创建一个返回第一个匹配的行号的函数

function lineNumber(needle,haystack){
    return lineNumberByIndex(haystack.indexOf(needle),haystack);
}

创建一个函数,返回每个匹配的行号

function lineNumbers(needle,haystack){
    if(needle !== ""){
        var i = 0,a=[],index=-1;
        while((index=haystack.indexOf(needle, index+1)) != -1){
            a.push(lineNumberByIndex(index,haystack));
        }
        return a;
    }
}

Fiddle

答案 3 :(得分:0)

我会相反地做

我认为由于只有一个正则表达式,它会具有更好的性能

var text="aaaaaaaaaaaaaaaaaaaaa\naaaaaaaabaaaaaaaaaa\naaaaaaaaaaaaaaaaaaa";
var RE=/b/g
var until=text.split(RE)
if (until.length>1){//found
   var linenumber=until[0].split(/\n/g).length
}

答案 4 :(得分:0)

match对象具有匹配索引和原始文本,因此您仅使用match就可以有效地计算换行符。

/**
 * Return the line number of the match, or -1 if there is no match.
 */
function matchLineNumber(m) {
  if (!m) {
    return -1
  }
  let line = 1
  for (let i = 0; i < m.index; i++) {
    if (m.input[i] == '\n') {
      line++;
    }
  }
  return line
}


const rx = /foo/
const ex1 = `foo`
const ex2 = `
hello
foo
`
const ex3 = `
hello
`

console.log(matchLineNumber(rx.exec(ex1)))
console.log(matchLineNumber(rx.exec(ex2)))
console.log(matchLineNumber(rx.exec(ex3)))

答案 5 :(得分:0)

谢谢@Shanimal 我更改了代码,还添加了列的位置:

describe('SampleCardComponent', () => {
  let mockStore;
  let dispatchSpy;
  let spectator: Spectator<SampleCardComponent>;

  const createComponent = createTestComponentFactory({
    component: SampleCardComponent,
    mocks: [ExperimentTimePipe],
  });

  beforeEach(() => {
    spectator = createComponent({
      props: { sampleHolder: SAMPLE_MOCK },
    });
    mockStore = spectator.get(MockStore);
    dispatchSpy = jest.spyOn(mockStore, 'dispatch');
  });

  test('should create', () => {
    expect(spectator).toBeTruthy();
  });

  test('should call editSample function', () => {
    const handleEditSpy = jest.spyOn(spectator.component, 'handleEdit');

    spectator.click('.button-edit');
    spectator.detectChanges();
    expect(handleEditSpy).toHaveBeenCalled();
    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    expect(dispatchSpy).toHaveBeenCalledWith({//...actionObject})
  });
});