【问题标题】:Matching multiple occurrences in javascript using a regex使用正则表达式匹配javascript中的多次出现
【发布时间】:2014-08-01 11:46:11
【问题描述】:

我正在使用 Javascript 和正则表达式来解析 "csv like flavor" 中的一些字符串,其中; 作为分隔符。到目前为止,我想出的正则表达式正在尝试获取所有出现的 pattern,例如:“INTERESTING1 (INTERESTING2; INTERESTING3)”。

我面临的问题是我只能匹配整个字符串中上一个模式的最后一次出现,而我想匹配所有出现的模式。我已经尝试了 Javascript 函数 exec()match() 有或没有一些循环,但我不知道我在做什么有什么问题?

var complexString = 'some boring stuff; some other boring stuff; interesting prefix (interesting inner stuff1; interesting inner stuff2; etc.); boring stuff; another interesting prefix (another interesting string 1; another interesting string 2; etc.)';
//var complexString = 'XXX';

// regex to apply
var roundBraketsRegex =  /.*;(.*)\((.*)\)/g; // string pattern: "INTERESTING1 (INTERESTING2; INTERESTING3)"
// array of matched groups
var matchesArray = roundBraketsRegex.exec(complexString);

var outputString = '';

if(matchesArray == null ) {
    outputString = 'NULL!!! ';
} 

// I have tried also the following commented line with stuff related to 
// while loops and functions like .exec() or .match()

//while ((matchesArray = roundBraketsRegex.match( complexString )) != null) {
outputString = outputString + ' ### ' + matchesArray[1] + ' ### ' + matchesArray[2] + ' ### NOT INTERESTED IN: ' + matchesArray[0];
//}


// print what has been found
console.log(document.getElementById('result'));
document.getElementById('result').innerHTML = outputString;

输出(我在 Stackoverflow 中手动添加了一些回车,只是为了让字符串更具可读性):

### another interesting prefix 
### another interesting string 1; another interesting string 2; etc. 
### NOT INTERESTED IN: some boring stuff; some other boring stuff; interesting prefix (interesting inner stuff1; interesting inner stuff2; etc.); boring stuff; another interesting prefix (another interesting string 1; another interesting string 2; etc.)

【问题讨论】:

  • 不要使用贪婪的.*,试试.*?
  • 是的,补充一下@hjpotter92 的说法,问题是您的正则表达式由于贪婪而一次匹配所有内容。* 如果您使用非贪婪匹配器。*?它只会匹配它需要的部分

标签: javascript regex csv pattern-matching


【解决方案1】:

您需要了解的关于正则表达式的一点是,匹配器的多次运行只会找到非重叠目标。如果您的正则表达式捕获过多,那么您将无法通过额外的运行找到额外的匹配项。

试试这个正则表达式,它捕获更少:

([^;]+?)\s+\(([^\)]*)\)

它有两个捕获组,它们抓取有趣的前缀和括号中的其他有趣的东西。请注意,您需要对结果使用 String.trim()。这是Regex 101 上解释的正则表达式。

这是最终的 JavaScript 解决方案,其中包括正则表达式:

var complexString = 'some boring stuff; some other boring stuff; interesting prefix (interesting inner stuff1; interesting inner stuff2; etc.); boring stuff; another interesting prefix (another interesting string 1; another interesting string 2; etc.)';
var roundBraketsRegex =  /([^;]+?)\s+\(([^\)]*)\)/g;        
var matchesArray;
var i = 1;

while (matchesArray = roundBraketsRegex.exec(complexString)) {
    var group1 = matchesArray[1].trim();
    var group2 = matchesArray[2].trim();
    console.log("Match #" + i + " [1]: '" + group1 + "' [2]: '" + group2 + "'");
    ++i;
}

这是运行上面的输出:

Match #1 [1]: 'interesting prefix' [2]: 'interesting inner stuff1; interesting inner stuff2; etc.'
Match #2 [1]: 'another interesting prefix' [2]: 'another interesting string 1; another interesting string 2; etc.'

希望对您有所帮助。

--乔纳森

【讨论】:

  • 这有助于缩小圆括号之前的前缀区域,但是我需要找到所有出现的重复模式。我已经尝试过@hjpotter(非贪婪匹配器)的建议,我认为这接近我想要实现的目标。
  • 我写的应该适用于所有情况,您只需要重新运行 exec 函数,直到它返回 null。我今天感觉不舒服,但如果到我回到办公室的时候你还没有解决它,我会用 Javascript 代码帮助你
猜你喜欢
  • 2012-02-24
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 2019-07-19
  • 1970-01-01
  • 1970-01-01
  • 2015-04-10
  • 2016-03-18
相关资源
最近更新 更多