RegEx使用RegExp.exec从字符串中提取所有匹配项

如何解决RegEx使用RegExp.exec从字符串中提取所有匹配项

| 我正在尝试解析以下类型的字符串:
[key:\"val\" key2:\"val2\"]
里面有任意的key:\“ val \”对。我想获取键名和值。 对于那些好奇的人,我试图解析任务战士的数据库格式。 这是我的测试字符串:
[description:\"aoeu\" uuid:\"123sth\"]
这是要强调的是,除了空格,冒号周围没有空格而且值始终用双引号引起来,键或值中的任何内容都可以位于键或值中。 在节点中,这是我的输出:
[deuteronomy][gatlin][~]$ node
> var re = /^\\[(?:(.+?):\"(.+?)\"\\s*)+\\]$/g
> re.exec(\'[description:\"aoeu\" uuid:\"123sth\"]\');
[ \'[description:\"aoeu\" uuid:\"123sth\"]\',\'uuid\',\'123sth\',index: 0,input: \'[description:\"aoeu\" uuid:\"123sth\"]\' ]
但是
description:\"aoeu\"
也与此模式匹配。如何找回所有比赛?     

解决方法

        继续循环调用
re.exec(s)
获得所有匹配项:
var re = /\\s*([^[:]+):\\\"([^\"]+)\"/g;
var s = \'[description:\"aoeu\" uuid:\"123sth\"]\';
var m;

do {
    m = re.exec(s);
    if (m) {
        console.log(m[1],m[2]);
    }
} while (m);
尝试使用此JSFiddle:https://jsfiddle.net/7yS2V/     ,        如果
pattern
具有全局标记
g
,6ѭ将以数组的形式返回所有匹配项。 例如:
const str = \'All of us except @Emran,@Raju and @Noman was there\';
console.log(
  str.match(/@\\w*/g)
);
// Will log [\"@Emran\",\"@Raju\",\"@Noman\"]
,        要遍历所有匹配项,可以使用
replace
函数:
var re = /\\s*([^[:]+):\\\"([^\"]+)\"/g;
var s = \'[description:\"aoeu\" uuid:\"123sth\"]\';

s.replace(re,function(match,g1,g2) { console.log(g1,g2); });
    ,        这是一个解决方案
var s = \'[description:\"aoeu\" uuid:\"123sth\"]\';

var re = /\\s*([^[:]+):\\\"([^\"]+)\"/g;
var m;
while (m = re.exec(s)) {
  console.log(m[1],m[2]);
}
这是基于Grasssea的答案,但更短。 注意,必须设置'g \'标志以使内部指针在调用之间向前移动。     ,        
str.match(/regex/g)
以数组形式返回所有匹配项。 如果出于某种神秘的原因,您需要ѭ14comes附带的其他信息,作为以前答案的替代方法,则可以使用递归函数来代替循环,如下所示(看起来也很酷)。
function findMatches(regex,str,matches = []) {
   const res = regex.exec(str)
   res && matches.push(res) && findMatches(regex,matches)
   return matches
}

// Usage
const matches = findMatches(/regex/g,str)
如前面的评论中所述,在正则表达式定义的末尾带有ѭ8以便在每次执行中向前移动指针很重要。     ,        基于Agus的函数,但我更喜欢只返回匹配值:
var bob = \"> bob <\";
function matchAll(str,regex) {
    var res = [];
    var m;
    if (regex.global) {
        while (m = regex.exec(str)) {
            res.push(m[1]);
        }
    } else {
        if (m = regex.exec(str)) {
            res.push(m[1]);
        }
    }
    return res;
}
var Amatch = matchAll(bob,/(&.*?;)/g);
console.log(Amatch);  // yeilds: [>,<]
    ,        可迭代项更好:
const matches = (text,pattern) => ({
  [Symbol.iterator]: function * () {
    const clone = new RegExp(pattern.source,pattern.flags);
    let match = null;
    do {
      match = clone.exec(text);
      if (match) {
        yield match;
      }
    } while (match);
  }
});
循环使用:
for (const match of matches(\'abcdefabcdef\',/ab/g)) {
  console.log(match);
}
或者,如果您想要一个数组:
[ ...matches(\'abcdefabcdef\',/ab/g) ]
    ,        我们终于开始看到内置的
matchAll
函数,有关说明和兼容性表,请参见此处。截至2019年4月,似乎支持Chrome和Firefox,但不支持IE,Edge,Opera或Node.js.好像它是在2018年12月起草的,所以给它一些时间来访问所有浏览器,但我相信它会实现的。 内置的
matchAll
函数很不错,因为它返回一个可迭代的函数。它还会为每次比赛返回捕获组!所以你可以做类似的事情
// get the letters before and after \"o\"
let matches = \"stackoverflow\".matchAll(/(\\w)o(\\w)/g);

for (match of matches) {
    console.log(\"letter before:\" + match[1]);
    console.log(\"letter after:\" + match[2]);
}

arrayOfAllMatches = [...matches]; // you can also turn the iterable into an array
似乎每个匹配对象都使用与“ 24”相同的格式。因此,每个对象都是匹配和捕获组的数组,以及三个附加属性
index
input
groups
。所以看起来像:
[<match>,<group1>,<group2>,...,index: <match offset>,input: <original string>,groups: <named capture groups>]
有关ѭ21的更多信息,还有一个Google开发人员页面。也有polyfills / shimms。     ,        如果您有ES9 (表示您的系统:Chrome,Node.js,Firefox等是否支持Ecmascript 2019或更高版本) 使用新的
yourString.matchAll( /your-regex/ )
。 如果您没有ES9 如果您使用的是较旧的系统,则此功能可轻松复制和粘贴
function findAll(regexPattern,sourceString) {
    let output = []
    let match
    // make sure the pattern has the global flag
    let regexPatternWithGlobal = RegExp(regexPattern,\"g\")
    while (match = regexPatternWithGlobal.exec(sourceString)) {
        // get rid of the string copy
        delete match.input
        // store the match data
        output.push(match)
    } 
    return output
}
用法示例:
console.log(   findAll(/blah/g,\'blah1 blah2\')   ) 
输出:
[ [ \'blah\',index: 0 ],[ \'blah\',index: 6 ] ]
    ,        这是我获得比赛的功能:
function getAllMatches(regex,text) {
    if (regex.constructor !== RegExp) {
        throw new Error(\'not RegExp\');
    }

    var res = [];
    var match = null;

    if (regex.global) {
        while (match = regex.exec(text)) {
            res.push(match);
        }
    }
    else {
        if (match = regex.exec(text)) {
            res.push(match);
        }
    }

    return res;
}

var regex = /abc|def|ghi/g;
var res = getAllMatches(regex,\'abcdefghi\');

res.forEach(function (item) {
    console.log(item[0]);
});
    ,        从ES9开始,现在有了一种更简单,更好的方法来获取所有匹配项以及有关捕获组及其索引的信息:
const string = \'Mice like to dice rice\';
const regex = /.ice/gu;
for(const match of string.matchAll(regex)) {
    console.log(match);
}
  // [\“老鼠\”,索引:0,输入:\“老鼠要切饭的骰子\”,组:   未定义]      // [\“ dice \”,索引:13,输入:\“老鼠要切成薄片的米饭\”,   组:未定义]      // [\“ rice \”,索引:18,输入:\“鼠标想切成小方块   rice \“,组:未定义] Chrome,Firefox,Opera当前支持该功能。根据您阅读本文的时间,请查看此链接以查看其当前支持。     ,        用这个...
var all_matches = your_string.match(re);
console.log(all_matches)
它将返回所有匹配项的数组...那会很好.... 但是请记住,它不会考虑组。它只会返回完整的匹配...     ,        我肯定会建议使用String.match()函数,并为其创建一个相关的RegEx。我的示例包含一个字符串列表,这在扫描用户输入中的关键字和短语时通常是必需的。
    // 1) Define keywords
    var keywords = [\'apple\',\'orange\',\'banana\'];

    // 2) Create regex,pass \"i\" for case-insensitive and \"g\" for global search
    regex = new RegExp(\"(\" + keywords.join(\'|\') + \")\",\"ig\");
    => /(apple|orange|banana)/gi

    // 3) Match it against any string to get all matches 
    \"Test string for ORANGE\'s or apples were mentioned\".match(regex);
    => [\"ORANGE\",\"apple\"]
希望这可以帮助!     ,这实际上并不能帮助您解决更复杂的问题,但是无论如何我都会发布此信息,因为对于那些没有像您一样进行全局搜索的人来说,这是一个简单的解决方案。 我已经将答案中的正则表达式简化了,以使其更清楚(这不是您确切问题的解决方案)。
var re = /^(.+?):\"(.+)\"$/
var regExResult = re.exec(\'description:\"aoeu\"\');
var purifiedResult = purify_regex(regExResult);

// We only want the group matches in the array
function purify_regex(reResult){

  // Removes the Regex specific values and clones the array to prevent mutation
  let purifiedArray = [...reResult];

  // Removes the full match value at position 0
  purifiedArray.shift();

  // Returns a pure array without mutating the original regex result
  return purifiedArray;
}

// purifiedResult= [\"description\",\"aoeu\"]
看起来比评论更冗长,这就是没有评论的样子
var re = /^(.+?):\"(.+)\"$/
var regExResult = re.exec(\'description:\"aoeu\"\');
var purifiedResult = purify_regex(regExResult);

function purify_regex(reResult){
  let purifiedArray = [...reResult];
  purifiedArray.shift();
  return purifiedArray;
}
请注意,任何不匹配的组都将在数组中列为“ 40”值。 该解决方案使用ES6扩展运算符来净化正则表达式特定值的数组。如果需要IE11支持,则需要通过Babel运行代码。     ,        这是一个没有while循环的单行解决方案。 订单保留在结果列表中。 潜在的缺点是 它为每个匹配项克隆正则表达式。 结果的形式与预期解决方案不同。您将需要再处理一次。
let re = /\\s*([^[:]+):\\\"([^\"]+)\"/g
let str = \'[description:\"aoeu\" uuid:\"123sth\"]\'

(str.match(re) || []).map(e => RegExp(re.source,re.flags).exec(e))
[ [ \'description:\"aoeu\"\',\'description\',\'aoeu\',index: 0,input: \'description:\"aoeu\"\',groups: undefined ],[ \' uuid:\"123sth\"\',\'uuid\',\'123sth\',input: \' uuid:\"123sth\"\',groups: undefined ] ]
    ,        我的猜测是,如果出现边缘情况,例如多余或缺少空格,则边界较少的表达式也可能是一个选择:
^\\s*\\[\\s*([^\\s\\r\\n:]+)\\s*:\\s*\"([^\"]*)\"\\s*([^\\s\\r\\n:]+)\\s*:\\s*\"([^\"]*)\"\\s*\\]\\s*$
  如果您想探索/简化/修改表达式,可以   在右上角的面板上进行了说明   regex101.com。如果您愿意,   也可以看这个   链接,它如何匹配   针对一些样本输入。 测试
const regex = /^\\s*\\[\\s*([^\\s\\r\\n:]+)\\s*:\\s*\"([^\"]*)\"\\s*([^\\s\\r\\n:]+)\\s*:\\s*\"([^\"]*)\"\\s*\\]\\s*$/gm;
const str = `[description:\"aoeu\" uuid:\"123sth\"]
[description : \"aoeu\" uuid: \"123sth\"]
[ description : \"aoeu\" uuid: \"123sth\" ]
 [ description : \"aoeu\"   uuid : \"123sth\" ]
 [ description : \"aoeu\"uuid  : \"123sth\" ] `;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match,groupIndex) => {
        console.log(`Found match,group ${groupIndex}: ${match}`);
    });
}
,        如果您希望使用一种更具功能性的方法并避免循环,则只需调用一个函数,直到结果为
null
,然后在每个捕获中将字符串切成捕获组的位置即可。
// The MatchAll Function
function matchAll (regexp,input,matches = []) {
  
  const regex = regexp.exec(input)

  if (regex === null) return matches

  // Filter out any undefined results
  const matched = regex.filter(i => i)
  
  // Destruct some common used values
  const { index } = regex
  const [ full,g2,g3] = matched

  // Slice the input string to last match
  const string = input.slice(index + full.length)
  
  // Do something with the captured groups
  // Push this into an array
  matches.push({
    prop: \'H\' + g1 + g3 + g3 + \'ary \' + g2
  })

  // Return
  return matchAll(regexp,string) 

}

// Record of matches
const matches = []

// The RegExp,we are looking for some random letters / words in string
const regExp = new RegExp(/(i{1}).*(did).*(l{1})/)

// An example string to parse
const testString = `Jeffrey Epstein didn\'t kill himself!`

// Run
matchAll(regExp,testString,matches)

// Returned Result
console.log(matches)
,        这是我的答案:
var str = \'[me nombre es] : My name is. [Yo puedo] is the right word\'; 

var reg = /\\[(.*?)\\]/g;

var a = str.match(reg);

a = a.toString().replace(/[\\[\\]]/g,\"\").split(\',\'));
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-