【问题标题】:Issue with getting the first matching item and its index position from a regex matching a string ( javascript)从匹配字符串(javascript)的正则表达式获取第一个匹配项及其索引位置的问题
【发布时间】:2021-06-09 02:47:33
【问题描述】:

我写了一个匹配字符串中所有函数名的正则表达式

Regex :- /([a-zA-Z ]*(?=\())/g
String:- (( MAX(1,2,3,4), min(1,2,3), max(3,4,5)))

上面的正则表达式通过检查后面跟“(”的一堆单词来匹配所有函数名。在这种情况下,匹配是MAXMIN MAX(除了我使用 match.filter(String) 过滤的一些空字符串。)

在我的一种情况下,我只需要“FIRST”匹配函数及其 START 和 STOP 索引。 所以,我写了下面的函数来获取它。

var re = /([a-zA-Z ]*(?=\())/g;    
var str = "max(1,2), min(1,2)";

while ((match = re.exec(str)) !== null) {
    console.log("match found at " + match.index);
  // Pick the first matching index from here ? 
}

但这会进入一个无限循环并且它没有给出所需的输出(我确定上面的函数有问题,但不太确定是什么)。

Example string2 = (((( max(34234,234234,344) min(1,2,3)))))*23 + max(23434, 234234,234234)))  - I only need the first matching function "max" from here along with it's start and stop index's.

【问题讨论】:

  • 考虑在这里使用解析器而不是正则表达式。
  • 括号内的文字索引有什么用?如果你只是想提取函数名和函数参数,你可以使用这个正则表达式:/([a-zA-Z]+) *\(([^\)]*)\)/g
  • @PeterThoeny 我只是想提取函数名称。我不需要参数列表。 (输出应该只是函数名 - 最大值、最小值及其起始字符位置和结束位置。

标签: javascript regex regex-group


【解决方案1】:

以下解决方案需要您提供的模式(特别是函数前后的空格。)

.match() 方法为起始位置提供了一个index,并使用字符串的.length 属性来获取结束位置:

let string = '(((( max(34234,234234,344) min(1,2,3)))))*23 + max(23434, 234234,234234)))';
let result = '';
while (result != null) {
  result = string.match(/\w+(?=\()/);
  if (result != null) {
    console.log('Found: ' + result, 'Start: ' + result.index, 'End: ' + parseInt(result[0].length + result.index));
  }
  string = string.split(result)[1];
}

【讨论】:

  • 感谢您的回复。我更多的是关注提取函数名称 - 最大值、最小值及其起始和结束位置。我不需要匹配参数。
  • 答案已编辑。请验证这是否是您正在寻找的。​​span>
【解决方案2】:

要索引获取函数名和参数吗?如果是的话,就不需要索引了,直接用这个正则就可以得到函数名和参数:/([a-zA-Z]+) *\(([^\)]*)\)/g:

const testCases = [
  'max(1,2), min(1,2)',
  '(( MAX(1,2,3,4), min (1,2,3), max(3,4,5)))'
];
let regex = /([a-zA-Z]+) *\(([^\)]*)\)/g;
let matches = testCases.forEach(str => {
  console.log('input: ' + str);
  let match = regex.exec(str);
  while(match) {
    console.log('- name: ' + match[1] + ', params: ' + match[2]);
    match = regex.exec(str);
  }
});

输出:

input: max(1,2), min(1,2)
- name: max, params: 1,2
- name: min, params: 1,2
input: (( MAX(1,2,3,4), min (1,2,3), max(3,4,5)))
- name: MAX, params: 1,2,3,4
- name: min, params: 1,2,3
- name: max, params: 3,4,5

此示例提取所有函数名称和参数对。如果您只对第一个感兴趣,请删除 while:

    let matches = testCases.forEach(str => {
      console.log('input: ' + str);
      let match = regex.exec(str);
      console.log('- name: ' + match[1] + ', params: ' + match[2]);
    });

正则表达式的解释:

  • ([a-zA-Z]+) - 捕获组 1:函数名称为 1+ alpha
  • * - 可选空格
  • \( - 左括号
  • ([^\)]*) - 捕获组 2:直到右括号之前的所有内容
  • \) - 右括号

请注意,我将您的正则表达式从 ([a-zA-Z ]*) 更改为 ([a-zA-Z]+) * 以避免误报,例如 MA X (1,2)

【讨论】:

  • @Veryon890:这符合您的需求吗?任何问题?愿意接受答案吗?请参阅答案旁边的灰色复选标记。
  • 很抱歉无法尽快回复您。正如我在问题中指出的那样,我也在寻找匹配的函数名称的索引(开始和停止)位置。您的解决方案只是给了我所有的功能和参数。我当然可以支持您的答案,但不确定我是否可以接受它作为解决方案。如果您愿意修改解决方案以适应所提出的问题,我肯定会接受。感谢您对正则表达式的详细解释。附言我想出了一种使用解析器的不同方法,但该解决方案对于登陆此处获取索引的人会有所帮助
猜你喜欢
  • 2013-06-12
  • 1970-01-01
  • 2020-12-11
  • 2014-09-10
  • 2016-02-14
  • 2011-12-04
  • 1970-01-01
  • 2010-09-11
  • 2021-04-27
相关资源
最近更新 更多