【问题标题】:Keep both the regex matches and the text between them保留正则表达式匹配和它们之间的文本
【发布时间】:2014-10-03 10:53:24
【问题描述】:

我正在尝试在 javascript 中创建一个方程解析器,因此我使用正则表达式将方程分解为各个部分。这是我目前正在使用的正则表达式:

var equation_string = '!#$123+456';
var operator = '(!|=|<|>)=|[=<>()^\\/*+-]';
var number = '(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?';
var variable = '[A-Za-z](_?[A-Za-z0-9]+)*';
var separator = ',';
var other = '\\S+';
var whitespace = '\\s+';

var pattern = new RegExp(number+'|'+operator+'|'+variable+'|'+separator+'|'+other+'|'+whitespace, 'g');

var equation_parts = equation_string.match(pattern);

我想保留等式的所有部分(用于跟踪我需要在等式中突出显示的位置,如果它格式不正确)。但是如果用户输入说'!#$ 123 + 456'会遇到问题,因为'\ S +'给了我一个部分'!#$ 123 + 456',而它应该是'!#$ ','123','+','456'.

我可以将 other 设置为 '\S',但这将是 '!'、'#'、'$'、'123'、'+'、'456',但我更愿意保留所有“其他”类型的模式。

将“其他”类型模式保持在一起的最佳方式是什么?或者有没有办法让我放弃“其他”模式并让正则表达式返回匹配的模式和它们之间的所有文本?

【问题讨论】:

  • 我的直觉是更改 other 以明确禁止其他正则表达式中的所有内容。
  • other 设置为\S 也是我对这个问题的回答,因为它会在每个位置有效地检查它是否是一个有效的标记,然后再获取字符。否则,您必须在负前瞻中复制 number|operator|variable|separator 才能获得相同的结果。
  • 我想过否定所有其他模式,但希望有一个优雅的替代方案。如果没有,那么我可能只会使用 '\S'。

标签: javascript regex regex-greedy


【解决方案1】:

一种解决方案是使用前瞻断言,这样只有在没有其他方法的情况下才会匹配:

(
    (?!(!|=|<|>)=|[=<>()^\\/*+-]) // this is the pattern for "operator", enclosed in a negative lookahead
    (?!(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?) // the pattern for "number"...
    (?![A-Za-z](_?[A-Za-z0-9]+)*) // "variable"...
    (?!,) // "separator"...
    (?!\s) // "whitespace"
    . // no other pattern matches, so it's ok to consume the next character.
)* // repeat this as often as possible.

另一种解决方案是根本不匹配 other 字符,按照以下方式进行操作:

var match_index= 0;
while ((match = pattern.exec(equation_string)) !== null)
{
    if(match.index > match_index)
    {
        var other= equation_string.substring(match_index, match.index);
        alert(other);
    }
    match_index= pattern.lastIndex;
}
if (match_index < equation_string.length){
    var other= equation_string.substring(match_index);
    alert(other);
}
// result: "!#$"

【讨论】:

  • 您的第二个解决方案正是我想要的,我对其进行了修改,以便它收集匹配项和其他项。我不确定的部分是为什么在while循环中需要'!== null'?在这种情况下 null 不等于 false,还是纯粹为了可读性而添加的?
  • @Ayb4btu:!== null 之所以存在,是因为我对 JavaScript 不是很有经验——它是这样工作的,所以我选择了它 :)
猜你喜欢
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多