简体   繁体   English

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

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

I am trying to make a regex to matches all the combinations of a given string. 我试图使一个正则表达式匹配给定字符串的所有组合。 For example of the string is "1234", answers would include: 例如,字符串为“ 1234”,答案将包括:

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

Nonexamples would include: 非示例包括:

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

If it matters, the programming language I am using is javascript. 如果有关系,我正在使用的编程语言是javascript。

Thank you for any help. 感谢您的任何帮助。

You may use this lookahead based assertions in your regex: 您可以在正则表达式中使用以下基于前瞻的断言:

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

RegEx Demo 正则演示

Here we have 4 lookahead assertions: 这里我们有4个前瞻性断言:

  • (?!(?:[^1]*1){2}) : Assert that we don't have more than one instance of 1 (?!(?:[^1]*1){2}) :断言我们的实例1
  • (?!(?:[^2]*2){2}) : Assert that we don't have more than one instance of 2 (?!(?:[^2]*2){2}) :断言我们最多有2个实例
  • (?!(?:[^3]*3){2}) : Assert that we don't have more than one instance of 3 (?!(?:[^3]*3){2}) :断言我们最多有3个实例
  • (?!(?:[^4]*4){2}) : Assert that we don't have more than one instance of 4 (?!(?:[^4]*4){2}) :断言我们最多有4个实例

We use [1234]+ to match any string with these 4 characters. 我们使用[1234]+来匹配具有这4个字符的任何字符串。

A combination of group captures using character classes and negative look-ahead assertions using back-references would do the trick. 使用字符类的组捕获和使用反向引用的否定超前断言的组合将达到目的。

Let's begin with simply matching any combination of 1, 2, 3, and 4 using a character class, [1-4] , and allowing any length from 1 to 4 characters. 让我们从简单地使用字符类[1-4]匹配1、2、3和4的任意组合开始,并允许1到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))); 

When that code is run, it's easy to see that although only numbers consisting of some combination of 1, 2, 3, and 4 are matched, it also is matching numbers with repeating combinations (eg 11, 22, 33, 112, etc). 运行该代码时,很容易看出,尽管只有由1、2、3和4的某种组合组成的数字才匹配,但它也与具有重复组合的数字匹配(例如11、22、33、112等) 。 Obviously, this was not what was desired. 显然,这不是期望的。

To prevent repeating characters requires a reference to previously matched characters and then a negation of them from any following matched characters. 为防止重复字符,需要先引用以前匹配的字符,然后再从后面匹配的所有字符中取反。 Negative look-aheads, (?!...) using a back-reference, \\1-9 , can accomplish this. 使用后向引用\\1-9负向超前(?!...)

Building on the previous example with a subset of the inputs (limiting to a max length of two characters for the moment) would now incorporate a group match surrounding the first character, ([1-4]) , followed by a negative look-ahead with a back-reference to the first capture, (?!\\1) , and finally a second optional character class. 在前面的示例中以输入的子集为基础(目前限制为两个字符的最大长度),现在将在第一个字符([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))); 

This matches the desired characters with no repetition! 这与所需字符匹配,没有重复!

Expanding this pattern to include back-references for each of the previously matched characters up to the desired max length of 4 yields the following expression. 扩展此模式以包括每个先前匹配的字符的反向引用,直到所需的最大长度为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))); 

Hope this helps! 希望这可以帮助!

You don't need to use regex for this. 您不需要为此使用正则表达式。 The snippet below does the following: 下面的代码段执行以下操作:

  1. Loop over possible combinations ( a => s ) ( 1 , 123 , 4321 , etc.) 遍历可能的组合( a => s )( 11234321 ,等)
  2. Copy the current combination so as not to overwrite it ( s2 = s ) 复制当前组合,以免覆盖( s2 = s
  3. Loop over the characters of test string ( x => ch ) ( 1234 => 1 , 2 , 3 , 4 ) 遍历测试字符串的字符( x => ch )( 1234 => 1234
  4. Replace common characters in the combination string shared with the test string ( s2.replace ) 用测试字符串( s2.replace )替换组合字符串中的公用字符
    • For example in the combination 1 , the 1 will be replaced when the loop gets to the character 1 in 1234 resulting in an empty string 例如,在组合1中, 1当环路到达该字符将被替换11234产生一个空字符串
  5. If the combination string's length reaches 0 ( s2.length == 0 ) write the result to the console and break out of the loop (no point in continuing to attempt to replace on an empty string) 如果组合字符串的长度达到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; } } }) 

Results: 结果:

1
123
4321
4312

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

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