regex 基于动态变量进行拆分,并在数组中保留分隔符

b0zn9rqh  于 2023-11-20  发布在  其他
关注(0)|答案(4)|浏览(121)

我需要根据一个会改变的动态分隔符拆分一个数组,并在结果数组中保留分隔符。
考虑下面的例子,我需要:

  • 拆分const match = 'somethingcatsomethingcatsomethingcat'
  • 使用分隔符const separator = 'cat'
  • 并得到以下数组作为结果:["something", "cat", "something", "cat", "something", "cat"]

以下是我尝试过的方法:

  1. const separator = 'cat'
  2. const match = 'somethingcatsomethingcatsomethingcat'
  3. const standardSplit = match.split(separator)
  4. console.log(standardSplit)
  5. // >> Array ["something", "something", "something", ""]
  6. const withPureRegex = match.split(/(cat)/)
  7. console.log(withPureRegex)
  8. // >> Array ["something", "cat", "something", "cat", "something", "cat", ""]
  9. // This is what I need, without the last element of an empty string.
  10. // But I need to pass in the separator dynamically.
  11. const regex = new RegExp(`/(${separator})/`, 'gi')
  12. const withStringLiteral = match.split(regex)
  13. console.log(withStringLiteral)
  14. // >> Array ["somethingcatsomethingcatsomethingcat"]

字符串
我不太擅长正则表达式。我读过一些关于在正则表达式中转义的文章,但似乎在RegExp中没有必要这样做?我尝试了RegExp的许多变体,但都没有运气。
有很多关于这个的问题,但我发现只有少数几个问题尝试使用动态分隔符来做,我发现的少数问题的答案使用字符串字面量和RegExp,就像我上面所做的那样。
如果我只需要执行一次,我会使用非正则表达式的方法,比如使用上面的第一个split方法,然后手动循环插入分隔符。但是在这种情况下,我会多次运行这个匹配/替换,如果可以避免的话,我不会增加更多的开销。

mctunoxg

mctunoxg1#

您可以使用.filter(Boolean)删除最后一个空项目。

Demo:

  1. const match = 'somethingcatsomethingcatsomethingcat';
  2. const separator = 'cat';
  3. const reg = new RegExp(`(${separator})`, 'g');
  4. const resArr = match.split(reg).filter(Boolean);
  5. console.log(resArr);

字符串

8wtpewkr

8wtpewkr2#

下面是一个非正则表达式的方法:

  • 在分离器上分离
  • 使用,${separator},重新加入阵列
  • ,上拆分新字符串
  • 过滤掉所有空值

注意,我使用了,作为新的分隔符;您可以使用原始字符串中没有出现的任何字符。

  1. const separator = 'cat'
  2. const match = 'somethingcatsomethingcatsomethingcat'
  3. const result = match.split(separator)
  4. .join(`,${separator},`)
  5. .split(',')
  6. .filter(Boolean)
  7. console.log(result)

字符串

展开查看全部
mlmc2os5

mlmc2os53#

您可以在正则表达式的匹配项上进行拆分

  1. (?<!^| ) *(?=cat)|(?<=cat) *(?! |$)

字符串
表达式如下:“match zero or more spaces provided they are not being preceded by a space or at the beginning of the string,and are followed by "cat"or|)match zero or more spaces provided they are preceded by "cat" and not being followed by a space or at the end of the string.”匹配零个或多个空格,前提是它们前面没有空格或在字符串的开头,后面有"cat" * 或 *(|)匹配零个或多个空格,前提是它们前面有"cat",后面没有空格或在字符串的结尾。
(?=cat)是一个 * 正的前瞻 *; (?<=cat)是一个 * 正的后向 *。(?<!^| )是一个 * 负的后向 *; (?! |$)是一个 * 负的前瞻 *。
Demo
该链接表明这两个字符串

  1. "catsomethingcatsomethingcat"
  2. "cat somethingcatsomething cat"


都被分割成数组

  1. ["cat", "something", "cat", "something", "cat"]


请注意,第二个字符串中的空格被删除了,而不是剩下" something"
注意,字符串被分割的某些匹配可能是零宽度的,例如将字符串"catsomething"分割为"cat""something"
愚蠢的(?<! |^)是将" catsomething"拆分为" cat""something"。如果我使用(?<!^),字符串将被拆分为" ""cat""something"。类似的(?! |$)而不是(?!$)

展开查看全部
eblbsuwk

eblbsuwk4#

  • "...我需要基于一个会改变的动态分隔符拆分一个数组,并将分隔符保留在结果数组中。..."*

使用 * 文本格式 * 和 RegExp 构造函数来创建 * 模式 *。
并且,使用 *look-around语法 ,来Assert之前和之后的位置。
这里有一个例子。

  1. (?=(?<!^)cat)|(?<=cat(?!$))

字符串

  1. let s = 'somethingcatsomethingcatsomethingcat'
  2. let d = 'cat'
  3. let p = new RegExp(`(?=(?<!^)${d})|(?<=${d}(?!$))`, 'gmi')
  4. let a = s.split(p)
  5. console.log(a.join(', '))

展开查看全部

相关问题