我正在寻找可满足以下要求的Javascript正则表达式引擎中使用的正则表达式。
我有一个文件,其内容结构如下(框内的文本):
Column 1 Column 2 Column 3
_______________________________________________________________________________________________
line 1|Heading 1 Heading 2 Heading 3 |
line 2| 123 456 Quisque imperdiet nibh nec fermentum sollicitudin. |
line 3| Vestibulum eu elit rutrum, eleifend ligula eu, interdum massa. |
line 4| 789 012 Suspendisse vel urna vulputate, porta ex ut, varius felis. |
line 5| Praesent a metus faucibus, porttitor magna at, fermentum libero. |
line 6| |
line 7| |
line 8|Heading 1 Heading 2 Heading 3 |
line 9| 123 456 Quisque imperdiet nibh nec fermentum sollicitudin. |
line 10| Vestibulum eu elit rutrum, eleifend ligula eu, interdum massa. |
line 11| 789 012 Suspendisse vel urna vulputate, porta ex ut, varius felis. |
line 12| Praesent a metus faucibus, porttitor magna at, fermentum libero. |
|_____________________________________________________________________________________________|
请注意,该文件不包含制表符,仅包含空格,但是我希望将正则表达式扩展为能够处理制表符。
列说明:
标题行只是字母。我已经知道如何创建正则表达式来匹配标题行。
前两列只能为空,或者只能包含任意位数的数字。
第三列也可以包含字母,数字和一些特殊字符的任意组合(任何类型的括号-弯曲,圆角,斜线,斜线,句号,连字符,等号)
第三列可能包含一个数字,后跟一个空格,后跟一个单词或特殊字符(这些示例是第三列中的有效条目5 RANDOMWORD
,5 (10)
,{{1 }})
第三列将永远不会包含:(1)一个数字,(2)仅用空格分隔的数字
我想要一个正则表达式,该表达式将允许我在第三列的内容中匹配多余的空格(两个或多个空格,制表符或制表符或空格的任意组合),以便我可以轻松地删除它们。目标是在第三列中找到多个空格,并用一个空格替换。
我想完全忽略标题行。
我也不想匹配前两列中出现的数字周围的空格。请注意,前两列可能并不总是包含数字。
到目前为止,我能够拼凑的正则表达式如下:
5 AND 10
/(?=^(?:(?!Heading 1 Heading 2 Heading 3).)*$)([ \t]*[\S]+[^\n]*)[ \t]{2,}/
允许我完全忽略标题行。
/(?=^(?:(?!Heading 1 Heading 2 Heading 3).)*$)/
允许我在前两列中没有数字的行中找到多个空格。但是,这个问题是,它会与第二列中的数字后面的空格匹配(例如第2行和第9行),我不想这样做。
如果Javascript支持落后,我认为这个问题很容易解决,否则我对如何解决这个问题感到困惑。
编辑1:抱歉,我最初的问题不清楚。我不是在寻找Javascript代码,而只是在Javascript正则表达式引擎中工作的正则表达式。
此外,相对于分多个步骤,我更喜欢单个regexp表达式。
编辑2:在规范中添加了更多详细信息。
编辑3:Lookbehind断言已被JavaScript标准接受,并且在编写此注释时,部分但不是全部JavaScript引擎都支持。请参阅:Javascript: negative lookbehind equivalent?。使用lookbehinds的单个正则表达式可能会实现此目的,但我尚未对此进行测试。
非常感谢您的帮助。
答案 0 :(得分:1)
在这种情况下,正则表达式将不起作用,因为前两列可能会被省略,并且前两列的字符集是第三列字符集的子集。因此,如果不知道列的宽度,就无法区分第三列的开头。
我认为解决此问题的唯一方法是检查带有标题的行,以查明每列的宽度,然后使用该行查找第三列的开头。它应该非常简单,您应该可以使用某种子字符串功能来做到这一点。
答案 1 :(得分:1)
我找不到只使用一次替换的解决方案。我认为您需要对该字符串进行多次迭代。
我相信这会起作用(userID Name function1Enabled function2Enabled function3Enabled
1 aaa True True False
2 bbb False True True
3 ccc True False True
),但我不确定:
set-cookie
旁注 :
/**
* /test/integration/controllers/entrance/login.test.js
*/
'use strict';
const supertest = require('supertest'); // also tried
describe('Entrance controllers', () => {
describe('/api/v1/entrance/login', () => {
before(() => {
this._url = '/api/v1/entrance/login';
return supertest(sails.hooks.http.app).get('/login')
.then(getRes => {
const reTokenCapture = /_csrf:\s*unescape\('([^']+)'\)/;
const foundToken = reTokenCapture.exec(getRes.text);
this._csrf = sails.config.security.csrf ? foundToken[1] : '';
this._cookie = getRes.headers['set-cookie'].join('; ');
});
});
it('should accept the session ID & CSRF token procured by GET /login', () => {
return supertest(sails.hooks.http.app)
.put(this._url)
.set('Cookie', this._cookie)
.set('X-CSRF-Token', this._csrf)
.send({
emailAddress: 'admin@example.com',
password: 'abc123',
})
.expect(200);
});
it('should reject requests without a CSRF token', () => {
return supertest(sails.hooks.http.app)
.put(this._url)
.set('Cookie', this._cookie)
.expect(403);
});
it('should reject requests without a session cookie', () => {
return supertest(sails.hooks.http.app)
.put(this._url)
.set('Cookie', '')
.set('x-csrf-token', this._csrf)
.expect(403);
});
it('should reject requests with invalid tokens', () => {
return supertest(sails.hooks.http.app)
.put(this._url)
.set('Cookie', 'sails.sid=foo; Path=/; HttpOnly')
.set('X-CSRF-Token', 'foo')
.send({
emailAddress: 'admin@example.com',
password: 'abc123',
})
.expect(403);
});
it('should reject requests with invalid credentionals', () => {
return supertest(sails.hooks.http.app)
.put(this._url)
.set('Cookie', this._cookie)
.set('X-CSRF-Token', this._csrf)
.send({
emailAddress: 'user@example.com',
password: 'password'
})
.expect(401);
});
it('should reject get requests', () => {
return supertest(sails.hooks.http.app)
.get(this._url)
.set('Cookie', this._cookie)
.set('X-CSRF-Token', this._csrf)
.send({
emailAddress: 'admin@example.com',
password: 'abc123',
})
.expect(404);
});
it('should reject post requests', () => {
return supertest(sails.hooks.http.app)
.post(this._url)
.set('Cookie', this._cookie)
.set('X-CSRF-Token', this._csrf)
.send({
emailAddress: 'admin@example.com',
password: 'abc123',
})
.expect(404);
});
});
});
是一个任意数字,与我认为此处段落的边距相对应; 答案 2 :(得分:1)
(我认为)仅凭JavaScript正则表达式是无法实现的。即使您设法扭曲了某些科学怪人的正则表达式怪物,也很难维护。
提供输入文字
Heading 1 Heading 2 Heading 3
123 456 Quisque imperdiet nibh nec fermentum sollicitudin.
Vestibulum eu elit rutrum, eleifend ligula eu, interdum massa.
789 012 Suspendisse vel urna vulputate, porta ex ut, varius felis.
Praesent a metus faucibus, porttitor magna at, fermentum libero.
Heading 1 Heading 2 Heading 3
123 456 Quisque imperdiet nibh nec fermentum sollicitudin.
Vestibulum eu elit rutrum, eleifend ligula eu, interdum massa.
789 012 Suspendisse vel urna vulputate, porta ex ut, varius felis.
Praesent a metus faucibus, porttitor magna at, fermentum libero.
一个人可以做
const blocks = text.split(/\n\n/g);
const result = blocks
.map(block => {
const [headingRow, ...rows] = block.split('\n');
const heading3index = headingRow.indexOf('Heading3');
return rows
.map(row => {
const [start, col3] = [row.slice(0, heading3index), row.slice(heading3index)];
return start + col3.replace(/\s\s+/g, ' ');
})
.join('\n');
})
.join('\n\n');