Вызначце, калі радок утрымлівае няцотная колькасць двукоссяў

Я спрабую напісаць рэгулярны выраз, якое можа вызначыць, калі радок утрымлівае няцотная колькасць " - двукоссі.

Які адказвае на гэтае пытанне ўжо дасягнуў чагосьці вельмі падобнае для вызначэння калі радок літар змяшчае няцотны лік пэўнай літары. Аднак у мяне паўсталі праблемы з адаптацыяй яго да маёй праблеме.

Тое, што я да гэтага часу, але гэта не зусім рабочая:

String regexp = "(\\b[^\"]*\"(([^\"]*\"){2})*[^\"]*\\b)";
        Pattern pattern = Pattern.compile(regexp);
        Matcher matcher = pattern.matcher("bbacac");
        if(matcher.find()){
            System.out.println("Found");
        }
        else
            System.out.println("Not Found");
2
гэта павінна быць рэгулярны выраз?
дададзена аўтар pascalhein, крыніца

6 адказы

Regex is a fairly poor solution for this. <-- I though you were talking about nesting, not pair matching.

Перабор ўсіх знакаў у радку, лічачы асобнікі " будзе больш хуткім і эфектыўным спосабам для дасягнення гэтай мэты.

int quoteCount = 0;
for(char ch : inputString.toCharArray())
{
  if(ch == '"') quoteCount++;
}

boolean even = quoteCount % 2 == 0;
10
дададзена
@Oded: Гэта пытанне было пра ўкладзенасці, а не спарванне. І (калі вы чыталі мой адказ), нават самыя старыя рэгулярныя выразы рухавікі могуць справіцца з гэтым выдатна, нават ацалелымі двукоссямі (якія ня-рэгулярны выраз рашэння будзе мець цяжкі час з).
дададзена аўтар Tim Pietzcker, крыніца
Тода! Ці можаце вы растлумачыць, чаму рэгулярны выраз з'яўляецца дрэнным рашэннем? Я aggree гэта крыху зразумець, але ёсць і іншыя прычыны?
дададзена аўтар CodyBugstein, крыніца
@Oded Гэта будзе прымяняцца толькі тады, калі ёсць магчымасць масіўных струн, і вельмі вялікая колькасць матчаў, правільна?
дададзена аўтар CodyBugstein, крыніца
Гэта не C #;)
дададзена аўтар Eng.Fouad, крыніца
@ Eng.Fouad - праўда. Прапушчаны тэг Java
дададзена аўтар Oded, крыніца
@Imray - убачыць гэта: stackoverflow.com/a/133684/1583
дададзена аўтар Oded, крыніца
@TimPietzcker - справядлівая кропка. Я прыняў гэтую праблему, каб быць ўкладзенасці пытанне.
дададзена аўтар Oded, крыніца

Калі вы хочаце, рэгулярны выраз, гэта проста выканаць:

boolean oddQuotes = subjectString.matches("[^\"]*\"(?:[^\"]*\"[^\"]*\")*[^\"]*");

Explanation: (without all the Java quote escapes):

[^"]*"   # Match any number of non-quote characters, then a quote
(?:      # Now match an even number of quotes by matching:
 [^"]*"  #  any number of non-quote characters, then a quote
 [^"]*"  #  twice
)*       # and repeat any number of times.
[^"]*    # Finally, match any remaining non-quote characters

Да гэтага часу, гэта, верагодна, больш павольна, чым проста «разлічваць каціроўкі» рашэнне. Але мы можам зрабіць адзін лепш: Мы можам канструяваць рэгулярныя выразы таксама апрацоўваць двукоссі экранаваныя, т.е .. е. не лічыць цытату, калі ён папярэднічае няцотная колькасць зваротнай касой рысы:

boolean oddQuotes = subjectString.matches("(?:\\\\.|[^\\\\\"])*\"(?:(?:\\\\.|[^\\\\\"])*\"(?:\\\\.|[^\\\\\"])*\")*(?:\\\\.|[^\\\\\"])*");

Зараз па агульным прызнанні, гэта выглядае жудасна, але ў асноўным з-за радка ратуючыся правілаў Java. Фактычнае рэгулярны выраз проста:

(?:       # Match either
 \\.      # an escaped character
|         # or
 [^\\"]   # a character except backslash or quote
)*        # any number of times.
"         # Then match a quote.
(?:       # The rest of the regex works just the same way (as above)
 (?:\\.|[^\\"])*"
 (?:\\.|[^\\"])*"
)*
(?:\\.|[^\\"])*
5
дададзена
Фантастычны! Ці можаце вы растлумачыць гэта коратка?
дададзена аўтар CodyBugstein, крыніца
Дзіўна, дзякуй!
дададзена аўтар CodyBugstein, крыніца
Вы не перашкаджала б адзначыць, што матчы() аўтаматычна прывязвае матчы - ці нават лепш, дадаць відавочныя якароў ў рэгулярным выразе. Гэта іншае пытанне патрэбныя толькі межы словаў, але гэта рэгулярны выраз MUST быць замацаваны на абодвух канцах, калі гэта мець якое-небудзь значэнне.
дададзена аўтар Alan Moore, крыніца

Не варта выкарыстоўваць рэгулярны выраз для гэтага. Проста перабіраць знакаў у радку і падлічыць «». Гэта будзе нашмат больш эфектыўным. Гэта (п) алгарытм высновы.

Асабліва, калі гэта проста і зрабіць рашэнне значна лягчэй чытаць, чым нейкі невыразны шаблон рэгулярнага выразы.

boolean odd = false;
for(int i=0; i
1
дададзена
Што складанасць, калі я выкарыстоўваю рэгулярны выраз?
дададзена аўтар CodyBugstein, крыніца
У лепшым выпадку O (п) у залежнасці ад вашых рэгулярных выразаў, за выключэннем складанага Regex, што прычыняе боль рамонтапрыдатнасць вашага кода. Гэта не ўсё пра колькасць ліній, неабходных, часам гэта плаціць, каб быць відавочнымі і шматслоўнымі.
дададзена аўтар mprivat, крыніца

Або, выкарыстоўвайце рэгулярны выраз, заменіце усё для двукоссі з пустымі радкамі, за выключэннем, і праверце даўжыню выніку.

1
дададзена

Вы можаце выкарыстоўваць раскол і праверыць, калі перавышаць колькасць элементаў вяртаецца масіва цотны ці няцотны, каб вымераць няцотная або цотная-насць частоты гэтага персанажа

String s = ".. what ever is in your string";
String[] parts = s.split("\"");
if(parts.size()%2){
   //String has odd number of quotes
}else{
   //String has even number of quotes
}
0
дададзена

Я павінен сказаць, што, верагодна, лепш проста падлічыць лік " s ўручную, але калі вы сапраўды хочаце рэгулярны выраз, вось адзін, які павінен працаваць:

"(^(([^\"]*\"){2})*[^\"]*$)"

Я проста звязала выраз пярэдняй і задняй часткі радкі і пераканайцеся, што ёсць толькі пары « s, слепа паглынаючы нічога не » паміж імі.

0
дададзена