是否可以在Javascript或node.js中找到多行输入(例如文件)的正则表达式匹配字符的行号?
答案 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;
}
}
答案 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})
});
});