【问题标题】:Splitting string into matching and non-matching groups in javascript在javascript中将字符串拆分为匹配和不匹配的组
【发布时间】:2018-01-12 02:36:33
【问题描述】:

我正在尝试将字符串拆分为与正则表达式匹配和不匹配的字符串数组:

string = "Lazy {{some_animal}} jumps over.."
# do some magic with regex /({{\s?[\w]+\s?}})/g and its negation
array = ["Lazy ", "{{some_animal}}", " jumps over.."]

在 javascript 中执行此操作的最佳性能方式?

【问题讨论】:

  • 这感觉像是一个 X/Y 问题,例如,你想做 X,认为你需要这个数组来做,所以你问如何创建这个数组 (Y)。 X是什么?我们或许可以提供其他不涉及此操作的有用方式。
  • 您可以将它们捕获为 3 个组并使用这些组创建一个数组

标签: javascript regex regex-negation


【解决方案1】:

您可以为此使用String match

下面的正则表达式只匹配任何不是胡须的东西,可选地被胡须包围。

示例 sn-p:

var str = "Lazy {{some_animal}} jumps over..";

const pattern = /\{*[^{}]+\}*/g;

var array = str.match(pattern);

console.log(str);
console.log(pattern);
console.log(array);

但为了更精确,正则表达式模式变得有点复杂。
下面的正则表达式匹配:

  1. “你想要什么”
    (每边 2 个胡须之间的单词)
  2. 或“你不想要的,然后是你想要的”
    (使用惰性匹配和正向前瞻)
  3. 或“剩下的”

var str = "Lazy {{some_animal}} jumps over..";

const pattern = /\{\{\w+\}\}|.+?(?=\{\{\w+\}\})|.+/g;

var array = str.match(pattern);

console.log(str);
console.log(pattern);
console.log(array);

最后但同样重要的是,邪恶的 SM 方法。
在同一个正则表达式上拆分 AND 匹配。并将它们连接成一个数组。
这种方法的缺点是不保留顺序。

var str = "Lazy {{some_animal}} jumps over..";

const pattern = /\{\{\w+\}\}/g;

var what_you_want = str.match(pattern);
var what_you_dont_want = str.split(pattern);

var array = what_you_want.concat(what_you_dont_want);

console.log(str);
console.log(pattern);
console.log(array);

【讨论】:

  • 好吧,如果字符串中有单个或不匹配的花括号,这将失败。
  • 嗯,这取决于你如何看待它。当然,第一种方法不算胡须。所以它也会在孤独的胡须上分裂。但如果输入字符串没有这些,那不是问题。如果是这样,结果数组中只会多出几条记录。
  • 结果数组中匹配和不匹配的元素没有区别。您需要对这些项目进行额外的匹配才能知道哪些是哪些
  • @Drenai 哇,对这么老的答案的评论。好吧,OP没有要求区分。如果这是您需要的,那么我建议您搜索它,或提出问题。
  • 这不是问题,只是后人的观察:-)
【解决方案2】:

我很确定一个简单的exec 循环将是您的最佳选择:

function getSegments(rex, str) {
  var segments = [];
  var lastIndex = 0;
  var match;
  rex.lastIndex = 0; // In case there's a dangling previous search
  while (match = rex.exec(str)) {
    if (match.index > lastIndex) {
      segments.push(str.substring(lastIndex, match.index));
    }
    segments.push(match[0]);
    lastIndex = match.index + match[0].length;
  }
  if (lastIndex < str.length) {
    segments.push(str.substring(lastIndex));
  }
  return segments;
}

var rex = /{{\s?[\w]+\s?}}/g;
var string = "Lazy {{some_animal}} jumps over..";

console.log(getSegments(/{{\s?[\w]+\s?}}/g, string));

注意我删除了捕获组;这种解决方案不需要它。

【讨论】:

  • 我确实喜欢您实际找到问题标题的解决方案。这显然比我只关注问题的解决方案付出了更多的努力。 :)
  • 它也可能有助于(如果用户想要)将匹配的段作为对象推送,例如{ match: "{{some_animal}}" },便于区分匹配段和文本段
猜你喜欢
  • 1970-01-01
  • 2015-10-30
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多