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

b0zn9rqh  于 12个月前  发布在  其他
关注(0)|答案(4)|浏览(101)

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

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

以下是我尝试过的方法:

const separator = 'cat'
const match = 'somethingcatsomethingcatsomethingcat'

const standardSplit = match.split(separator)
console.log(standardSplit)
// >> Array ["something", "something", "something", ""]

const withPureRegex = match.split(/(cat)/)
console.log(withPureRegex)
// >> Array ["something", "cat", "something", "cat", "something", "cat", ""]
// This is what I need, without the last element of an empty string.
// But I need to pass in the separator dynamically.

const regex = new RegExp(`/(${separator})/`, 'gi')
const withStringLiteral = match.split(regex)
console.log(withStringLiteral)
// >> Array ["somethingcatsomethingcatsomethingcat"]

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

mctunoxg

mctunoxg1#

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

Demo:

const match = 'somethingcatsomethingcatsomethingcat';
const separator = 'cat';

const reg = new RegExp(`(${separator})`, 'g');
const resArr = match.split(reg).filter(Boolean);

console.log(resArr);

字符串

8wtpewkr

8wtpewkr2#

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

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

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

const separator = 'cat'
const match = 'somethingcatsomethingcatsomethingcat'

const result = match.split(separator)
  .join(`,${separator},`)
  .split(',')
  .filter(Boolean)

console.log(result)

字符串

mlmc2os5

mlmc2os53#

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

(?<!^| ) *(?=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
该链接表明这两个字符串

"catsomethingcatsomethingcat"
"cat somethingcatsomething cat"


都被分割成数组

["cat", "something", "cat", "something", "cat"]


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

eblbsuwk

eblbsuwk4#

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

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

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

字符串

let s = 'somethingcatsomethingcatsomethingcat'
let d = 'cat'
let p = new RegExp(`(?=(?<!^)${d})|(?<=${d}(?!$))`, 'gmi')
let a = s.split(p)

console.log(a.join(', '))

相关问题