Регулярное выражение для сопоставления строки с четным числом кавычек - PullRequest
2 голосов
/ 21 марта 2009

Я придумал: ([^"]*["][^"]*["][^"]*)*

Работает во всех случаях, кроме пустой строки. Я думал, что это сработает, потому что последняя звезда соответствует предыдущему токену ноль или более раз.

Есть идеи?

Также, если есть лучший способ сделать это, пожалуйста, дайте мне знать и объясните это подробно.

Решением должно быть регулярное выражение, поскольку местом, где оно будет использоваться, является крючок, для которого требуется регулярное выражение.

Он также должен соответствовать строке без кавычек, поскольку ноль - четное число

Ответы [ 5 ]

6 голосов
/ 21 марта 2009

Попробуйте это выражение:

^(?:[^"]+|"[^"]*")*$

Соответствует последовательности, состоящей из любого символа, кроме кавычек ([^"]+), или пары кавычек с любым символом, отличным от кавычек между ("[^"]*"). И квантификатор * учитывает пустую строку.

4 голосов
/ 21 марта 2009

ваше регулярное выражение должно соответствовать полностью пустой строке, но не, например, строка, состоящая из одного пробела, потому что ваше регулярное выражение утверждает, что если строка не является полностью пустой , она должна содержать хотя бы одну двойную кавычку. Это связано с тем, что в регулярном выражении есть токены ["], за которыми не следует *.

Правильный способ думать о необходимом регулярном выражении заключается в следующем: вы хотите сопоставить (строка без двойных кавычек), затем (двойные кавычки) плюс (строка без двойных кавычек), за которыми следует (двойная) кавычка, а затем (строка без двойных кавычек), а затем повторите, начиная с первого «с последующим» до бесконечности. Строка без двойных кавычек - [^ "] *, поэтому вы получите (пробел добавлен для удобства чтения):

[^"]* (" [^"]* " [^"]*)*

Если вы сравните это с вашим регулярным выражением, первое [^ "] * было перемещено из повторения.

2 голосов
/ 21 марта 2009

На основании вашего регулярного выражения:

([^"]*["][^"]*["][^"]*)*

Добавить якоря линии:

^([^"]*["][^"]*["][^"]*)*$

Добавить возможность совпадения с не- ":

^([^"]*["][^"]*["][^"]*|[^"]?)*$

Этот последний шаг не позволяет ничего подобрать или использовать персонажа. Это позволяет сопоставлять строки, не имеющие ". Обратите внимание, что необходимы якоря линии, в противном случае подстроки будут соответствовать этому.

Бонус: предотвращение обратных ссылок на группы (именование / нумерация групп может немного замедлить механизм регулярных выражений):

^(?:[^"]*["][^"]*["][^"]*|[^"]?)*$
2 голосов
/ 21 марта 2009

Похоже, регулярное выражение не является подходящим инструментом для работы. Изменить: Тем не менее, вы, кажется, ограничены этим. Это не отвечает на ваш вопрос, учитывая это ограничение, но без него будет отлично работать.

Просто перебери свою строку и посчитай. Пример C:

bool hasEvenNumberOfQuotes(const char *str)
{
    bool even = true;

    while(*str != '\0')
    {
        if(*str == '"')
            even = !even;

        ++str;
    }

    return even;
}
0 голосов
/ 21 марта 2009
import re

def hasPairedQuotes(s):
    stripped = re.sub('[^"]', "", s)
    return len(stripped) % 2 == 0

>>> hasPairedQuotes("")
True
>>> hasPairedQuotes('""')
True
>>> hasPairedQuotes('"""')
False
>>> hasPairedQuotes('"Hello world!""')
False
>>> hasPairedQuotes('"Hello world!"')
True

Хорошо, вы хотите регулярное выражение, вот регулярное выражение: ^[^"]*("[^"]*")*[^"]*$ ... но я думаю, что разница в удобочитаемости и удобстве обслуживания говорит сама за себя.

>>> re.match(r'^[^"]*("[^"]*"[^"])*$', 'Hello ""')
<_sre.SRE_Match object at 0xb7cc0ce0>
>>> re.match(r'^[^"]*("[^"]*"[^"])*$', 'Hello "" "')
>>> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...