繁体   English   中英

正则表达式匹配给定字符串的所有组合

[英]Regex to match all combinations of a given string

我试图使一个正则表达式匹配给定字符串的所有组合。 例如,字符串为“ 1234”,答案将包括:

  1. “ 1”
  2. “ 123”
  3. “ 4321”
  4. “ 4312”

非示例包括:

  1. “ 11”
  2. “ 11234”
  3. “ 44132”

如果有关系,我正在使用的编程语言是javascript。

感谢您的任何帮助。

您可以在正则表达式中使用以下基于前瞻的断言:

^(?!(?:[^1]*1){2})(?!(?:[^2]*2){2})(?!(?:[^3]*3){2})(?!(?:[^4]*4){2})[1234]+$

正则演示

这里我们有4个前瞻性断言:

  • (?!(?:[^1]*1){2}) :断言我们的实例1
  • (?!(?:[^2]*2){2}) :断言我们最多有2个实例
  • (?!(?:[^3]*3){2}) :断言我们最多有3个实例
  • (?!(?:[^4]*4){2}) :断言我们最多有4个实例

我们使用[1234]+来匹配具有这4个字符的任何字符串。

使用字符类的组捕获和使用反向引用的否定超前断言的组合将达到目的。

让我们从简单地使用字符类[1-4]匹配1、2、3和4的任意组合开始,并允许1到4个字符的任何长度。 {1,4}

 const regex = /^[1-4]{1,4}$/; // Create set of inputs from 0 to 4322 const inputs = Array.from(new Array(4323), (v, i) => i.toString()); // Output only values that match criteria console.log(inputs.filter((input) => regex.test(input))); 

运行该代码时,很容易看出,尽管只有由1、2、3和4的某种组合组成的数字才匹配,但它也与具有重复组合的数字匹配(例如11、22、33、112等) 。 显然,这不是期望的。

为防止重复字符,需要先引用以前匹配的字符,然后再从后面匹配的所有字符中取反。 使用后向引用\\1-9负向超前(?!...)

在前面的示例中以输入的子集为基础(目前限制为两个字符的最大长度),现在将在第一个字符([1-4])周围合并组匹配,然后进行否定的前瞻向后引用第一个捕获(?!\\1) ,最后引用第二个可选字符类。

 const regex = /^([1-4])(?!\\1)[1-4]?$/; // Create set of inputs from 0 to 44 const inputs = Array.from(new Array(45), (v, i) => i.toString()); // Output only values that match criteria console.log(inputs.filter((input) => regex.test(input))); 

这与所需字符匹配,没有重复!

扩展此模式以包括每个先前匹配的字符的反向引用,直到所需的最大长度为4都会产生以下表达式。

 const regex = /^([1-4])((?!\\1)[1-4])?((?!\\1|\\2)[1-4])?((?!\\1|\\2|\\3)[1-4])?$/; // Create set of inputs from 0 to 4322 const inputs = Array.from(new Array(4323), (v, i) => i.toString()); // Output only values that match criteria console.log(inputs.filter((input) => regex.test(input))); 

希望这可以帮助!

您不需要为此使用正则表达式。 下面的代码段执行以下操作:

  1. 遍历可能的组合( a => s )( 11234321 ,等)
  2. 复制当前组合,以免覆盖( s2 = s
  3. 遍历测试字符串的字符( x => ch )( 1234 => 1234
  4. 用测试字符串( s2.replace )替换组合字符串中的公用字符
    • 例如,在组合1中, 1当环路到达该字符将被替换11234产生一个空字符串
  5. 如果组合字符串的长度达到0s2.length == 0 ),则将结果写入控制台并退出循环(继续尝试替换空字符串没有意义)

 const x = "1234" const a = ["1","123","4321","4312","11","11234","44132"] a.forEach(function(s) { var s2 = s for(var ch of x) { s2 = s2.replace(ch, '') if(s2.length == 0) { console.log(s); break; } } }) 

结果:

1
123
4321
4312

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM