2016-12-25 69 views
1

我有0和1的字符串。 我想要一個正則表達式,使得0的數量少於1的數量。正在計數的正則表達式

例子:

0111 - match (there is 1x0 and 3x1 and 1 < 3) 
00011 - pattern fails (3x0 and 2x1 but 3<2 is false) 
0101010 - pattern fails (4x0 and 3x1 but 4<3 is false) 
+0

請指定正則表達式的風味。 – revo

+0

'我有'.......'我想'....... –

回答

2

隨着PCRE和Perl的可能,你可以使用遞歸模式做到這一點:

^((?:0(?1)??1|1(?1)??0)*+)(?:1(?1))+$ 

demo

細節:

^ 
(# group 1: matches balanced 0 and 1 
    (?: 
     0(?1)??1 # part that starts with 0 and ends with 1 
       # (?1) calls the group 1 subpattern itself (recursion) 
     | 
     1(?1)??0 # same thing for 1 ... 0 
    )*+ # repeat 
) 
(?: 
    1  
    (?1) 
)+ # ensure there's at least one 1 that isn't matched by (?1) 
$ 

使用.NET正則表達式引擎:

^(?>(?<c>0)|(?<-c>1))*(?(c)(?!$))(?:1(?>(?<c>0)|(?<-c>1))*(?(c)(?!$)))+$ 

demo

此時更直觀:

(?<c>...)增加一個計數器c和(?<-c>...)減小相同的計數器。當計數器c不爲零時,條件(?(c)(?!$))失敗(?!$)是始終失敗的子模式)

此模式的全局結構比前面所述一樣:

^ (balanced parts)* (?: 1 (balanced parts)*)+ $ 

的其他可能的結構與PCRE是:

^ (?: balanced parts | (1))*+ (force to fail if capture group doesn't exist) $ 

PCRE:

^(?:((?:0(?1)?1|1(?1)?0)+)|(1))*+(?(2)|(*F))$ 
+0

正如我記得這個問題被指定爲Peter Linz's * Formal Languages和Automata *書籍的一個練習部分。不過,我應該問,你是如何將這個想法作爲強制性表達而不是在第一個捕獲組中交替的? – revo

+0

@revo:'(?:1(?1))+'只是'1(?:1 |(?1))*'的改進形式(展開形式)。你也可以這樣寫:https://regex101.com/r/zE1Nqt/1 –

+0

1)當我用這種方式思考'S - > SS | 0S1 | 1S0 | 1S | 1'我不能瞭解你如何制定'1(?1)'強制性的。爲什麼它是強制性的? (我應該說語法的製作不會產生例如'w = 10110',所以如果你點亮的話我會很感激)2)我們應該怎麼做才能避免使用粗糙零的字符串的CB:[**'111111111110000000000011101011010001111111 ** ](https://regex101.com/r/alpwgU/2)? – revo

1

正則表達式用於匹配的模式,但你似乎想計算字符數的情況。就我所知,這不是正則表達式。

你需要做的是創建一個數組或其他結構來保存你之後特定字符的計數器值。然後,您將迭代輸入字符串,並根據手頭的角色更新相應的計數器。

1

我認爲你可以實現你的目標沒有正則表達式。

FOREACH:

string s = "10101010011"; 
int zeros = 0; 
int ones = 0; 
foreach (char c in s) 
{ 
    if (c == '0') 
    { 
     zeros++; 
    } 
    else 
    { 
     ones++; 
    } 
} 
Console.WriteLine(zeros < ones); 
Console.ReadLine(); 

LINQ:

string s = "10101010011"; 
int zeros = s.Count(x => x == '0'); 
int ones = s.Count(x => x == '1'); 
Console.WriteLine(zeros < ones); 
Console.ReadLine(); 
1

既然你沒有指定的語言。這是你如何在Python中實現它,而不使用正則表達式。您可以將此邏輯移植到您的語言。

a= """0111 
00011 
0101010""" 

a = a.split('\n') 
print a 

for b in a: 
    zeroes = list(b).count('0') 
    ones = list(b).count('1') 
    if zeroes < ones: 
     print b 

輸出:

['0111', '00011', '0101010'] 
0111