【问题标题】:regex to replace spaces with underscores between two specified strings正则表达式用下划线替换两个指定字符串之间的空格
【发布时间】:2020-05-11 13:58:04
【问题描述】:

我需要一个正则表达式来用下划线替换某些特定 json 键值中的空格。

我正在使用 gulp-replace 进行替换。这是我的wip:

const method1 = /(?<=title": ")(\s+)(?=",)/g; // not working 
const method2 = /(?:\G(?!^)|title": ")[^" ]*\K[ ]/g; // works in regex101.com but not when run as part of the gulp replace task below

gulp.task('spaceReplace', function () {
      return gulp
        .src(['src/data/data.json'])
        .pipe(replace(method2, '_'))
       .pipe(gulp.dest('src/data/output/'));
  });

输入(json数据文件):

{
 "stories": {
    "story1_category": "",
    "story1_title": "Blue Monday",
    "story1_link": "",
    "story2_category": "",
    "story2_title": "The Meaning Of Life",
    "story2_link": "",
    "story3_category": "",
    "story3_title": "Blind Mans Bluff",
    "story3_link": "",
    "story4_category": "",
    "story4_title": "The Art Of Fly-Fishing",
    "story4_link": "",
    "story5_category": "",
    "story5_title": "King Of The Hill"
    }
}

期望的输出:

{
 "stories": {
    "story1_category": "",
    "story1_title": "Blue_Monday",
    "story1_link": "",
    "story2_category": "",
    "story2_title": "The_Meaning_Of_Life",
    "story2_link": "",
    "story3_category": "",
    "story3_title": "Blind_Mans_Bluff",
    "story3_link": "",
    "story4_category": "",
    "story4_title": "The_Art_Of_Fly-Fishing",
    "story4_link": "",
    "story5_category": "",
    "story5_title": "King_Of_The_Hill"
    }
}

我尝试了一个表达式来匹配每个节点并选择有效的整个值:

(?<=title": ")(.*?)(?=",)

然后我尝试以下更新 - 想法是我将部分替换为“匹配所有”的表达式,该表达式只匹配该值中的空格:

(?<=title": ")(\s+)(?=",)

但它不起作用。 为什么上述方法不起作用?

我还尝试了另一种基于this的方法

(?:\G(?!^)|title": ")[^" ]*\K[ ]

这在使用 https://regex101.com/ 测试时匹配,但在 https://regexr.com/ 测试时不匹配,当我尝试在我的 gulp 任务中将它用作我的 method1 正则表达式时它也不起作用

为什么上述方法也不起作用?什么是可以匹配 json 树中每个标题值中的空格的解决方案?

【问题讨论】:

  • 永远不要对这类事情使用正则表达式。您可以迭代这些值并像那样更改它们。它更安全。
  • 第一个模式不起作用,因为您正在匹配 \s+,这是示例数据中不存在的一个或多个空白字符。如果支持正向后视,您可以使用(?&lt;=title": ")([^"]+)(?=",)。在第二种模式中,您使用 \G\K,您可能在 regex101 上启用了 pcre 支持,但 Javascript 不支持。
  • 您使用什么语言/工具?来自regex tag info:“由于正则表达式尚未完全标准化,所有带有此标签的问题还应包含一个指定适用的编程语言或工具的标签。”
  • @Toto 抱歉缺少上下文。使用 javascript 作为 gulp 框架的一部分来运行任务。不确定我是否可以在现有帖子中添加其他标签 - 但如果可以的话

标签: javascript json regex replace gulp


【解决方案1】:

将正则表达式应用于 JavaScript 对象永远不会起作用,而将其应用于 JSON(字符串)可能会起作用,但当字符串复杂时会导致不希望的结果。你想把它分解成小块,只更换需要更换的部分。所以你想遍历键和值并改变它们:

const JSON = {
  "stories": {
    "story1 category": "",
    "story1 title": "Blue Monday",
    "story1 link": "",
    "story2 category": "",
    "story2 title": "The Meaning Of Life",
    "story2 link": "",
    "story3 category": "",
    "story3 title": "Blind Mans Bluff",
    "story3 link": "",
    "story4 category": "",
    "story4 title": "The Art Of Fly-Fishing",
    "story4 link": "",
    "story5 category": "",
    "story5 title": "King Of The Hill"
  }
}

//use Object.keys to loop over every key
Object.keys(JSON.stories).forEach( (item) => {
  //first update the item's value
  JSON.stories[item] = JSON.stories[item].replace(/\s+/g, "_");  
  
  //add a new property to stories containing the changed item key
  const replacedKey = item.replace(/\s+/g, "_");
  //set the item's value to the new key
  JSON.stories[replacedKey] = JSON.stories[item];
  //delete the old key
  delete JSON.stories[item];
});

console.log(JSON);

【讨论】:

  • 感谢您的帮助 Mouser - 我很欣赏这是一个比我原来的方式更好的解决方案。我正在尝试将您的解决方案用于我的 gulp 任务,但没有完成。在进一步回复中发布我的尝试。
【解决方案2】:

将@Mouser 的解决方案应用到我的 gulp 任务中 - 我认为它类似于以下内容,但也失败了。非常感谢任何输入:

var storiesData = require('./src/data/stories.json'); 

gulp.task('spaceReplace', function () {
    return Object.keys(storiesData).forEach( (item) => {
        return gulp
            .src(storiesData[item])
            .pipe(replace(/\s+/g, '_'))
            .pipe(gulp.dest('src/data/'));
    });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    相关资源
    最近更新 更多