正则表达式重复字符串

时间:2016-06-10 17:11:45

标签: python regex

我需要以下文字的正则表达式。 我已经尝试了很多东西,但总是只匹配最后两组,或者它匹配的是#Text1& someText 2& someText 3&'作为一个群体...

someText 1 & someText 2 & someText 3
someText 1 & someText 2 & someText 3 & someText 4

我期待的是两场比赛:

匹配1:

  • someText 1
  • someText 2
  • someText 3

比赛2:

  • someText 1
  • someText 2
  • someText 3
  • someText 4

4 个答案:

答案 0 :(得分:0)

这适用于提供的示例文本和所需结果:

\S+\s\d

\S+ match any non-white space character [^\r\n\t\f ]
Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]

\s match any white space character [\r\n\t\f ]
\d match a digit [0-9]

答案 1 :(得分:0)

如果我正确阅读,您可以尝试捕获任意数量的'&'每行分隔的项目到捕获组中。

使用纯正则表达式,这是不可能的。由于正则表达式作为状态机运行,因此您不能拥有任意数量的捕获组。任何给定的表达式都有固定数量的捕获组,这些捕获组可能会捕获任何东西数字由表达式决定(基本上,你有多少套括号)并且不能改变。

相反,您可以执行类似捕获分隔符的操作。因此,不要试图匹配" someText 3",匹配并拆分"&"。

我不知道您使用的是哪种语言,所以这里是Javascript中的一些示例代码:

// Test input, as provided.
var inputString = "someText 1 & someText 2 & someText 3\nsomeText 1 & someText 2 & someText 3 & someText 4";

// Break up the lines. (Replace this with however you get your lines separated.)
var line_delimit = /[\n\r]+/;
var lines = inputString.split(line_delimit);

// Split each line on ampersands.
var group_delimit = /\s*&\s*/;
var matches = [];
lines.forEach(function(line){
    matches.push(line.split(group_delimit));
});

// Display.
for (var index in matches){
    console.log("Match " + index + ":");
    console.log(JSON.stringify(matches[index],null,2));
    console.log();
}

答案 2 :(得分:0)

我认为James是关于某事的,但他并没有完全达到目标。

您不应该尝试使用纯正则表达式执行此操作。保持简单。首先,您应该将字符串拆分为&

>>> s = 'someText 1 & someText 2 & someText 3 & someText 4'
>>> s.split('&')
['someText 1 ', ' someText 2 ', ' someText 3 ', ' someText 4']

(这当然假设someText不能包含&,但如果可以的话,你会遇到很多更难的问题。)

然后我们需要strip关闭前导和尾随空格:

>>> s_clean = [i.strip() for i in s.split('&')]
>>> s_clean
['someText 1', 'someText 2', 'someText 3', 'someText 4']

现在我们可以使用正则表达式来过滤掉不匹配的元素:

>>> import re
>>> [i for i in s_clean if re.match('.+\s+[0-9]+', i)]
['someText 1', 'someText 2', 'someText 3', 'someText 4']

(注意re.match实际上返回一个Match对象,而不是布尔值。)

这给了你想要的东西。缩短它:

s = 'someText 1 & someText 2 & someText 3 & someText 4'
s_clean = [i.strip() for i in s.split('&')]
result = [i for i in s_clean if re.match('.+\s+[0-9]+', i)]

如果你愿意的话,你可以将它变成一个单行,但它看起来会更加混乱。

现在对自己重复以下第3行:

  

正则表达式不是所有文本处理问题的解决方案。

答案 3 :(得分:0)

鉴于您使用的是Python,您需要re模块和re.findall方法。

例如,您可以使用:

import re
import fileinput

p1 = re.compile(r'\s*(\S[^&]*)\s+(&|$)')

for line in fileinput.input():
    matches = p1.findall(line)
    print "Line: ", line
    for match in matches:
        print "Match: ", match
    print ""

正则表达式查找可选的空格(\s*),然后捕获非白色空格,后跟零个或多个非符号((\S[^&]*)),后跟空格和{{1} }或字符串结尾(&)。

给定包含您在问题中显示的两个样本行的输入:

\s+(&|$)

输出是:

someText 1 & someText 2 & someText 3
someText 1 & someText 2 & someText 3 & someText 4

可以应用无限的调整,例如使用Line: someText 1 & someText 2 & someText 3 Match: ('someText 1', '&') Match: ('someText 2', '&') Match: ('someText 3', '') Line: someText 1 & someText 2 & someText 3 & someText 4 Match: ('someText 1', '&') Match: ('someText 2', '&') Match: ('someText 3', '&') Match: ('someText 4', '') ,因此只有一个捕获组 - 输出只是'(?:&|$)'字符串。您也可以使用非贪婪的匹配someText N,尽管它写得很好。如果存在相邻的[^&]*?个字符,则第二个字符将被视为下一个字符串开头的非空白空间。如果你认为这可能是一个真正的问题,你可以解决这个问题。