Согласование шаблона в строке с регулярным выражением в Python [дубликат]

JSON не поддерживает включение определений / выражений function.

Вместо этого вы можете определить объект commands с помощью function, который вам нужен, и просто передать commandName:

// client-side

var commands = {
    log: function (param) {
        console.log(param);
    }
};

socket.on('executecommand', function(data){
    var a = 'foo';
    commands[data.commandName](a);
});
// server-side

socket.emit('executecommand', { commandName: 'log' });

Вы также можете использовать fn.apply() для передачи аргументов и проверить, что commandName соответствует команде с in :

// client-side
var commands = { /* ... */ };

socket.on('executecommand', function(data){
    if (data.commandName in commands) {
        commands[data.commandName].apply(null, data.arguments || []);
    } else {
        console.error('Unrecognized command', data.commandName);
    }
});
// server-side

socket.emit('executecommand', {
    commandName: 'log',
    arguments: [ 'foo' ]
});

345
задан martineau 27 January 2018 в 02:28
поделиться

7 ответов

re.match закреплен в начале строки. Это не имеет ничего общего с новыми строками, поэтому это не то же самое, что использовать ^ в шаблоне.

Поскольку в документации re.match говорится:

< blockquote>

Если ноль или более символов в начале строки соответствуют шаблону регулярного выражения, верните соответствующий экземпляр MatchObject. Вернуть None, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.

Примечание. Если вы хотите найти соответствие в любом месте строки, используйте вместо этого search().

re.search ищет всю строку, поскольку в документации указано :

Просканировать строку, ищущую место, где шаблон регулярного выражения создает совпадение, и возвращает соответствующий MatchObject. Возврат None, если никакая позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в некоторой точке строки.

Так что если вам нужно совпадение в начале строки или совпадение со всей строкой match. Это быстрее. В противном случае используйте search.

В документации имеется специальный раздел для match vs. search , который также охватывает многострочные строки:

Python предлагает две различные примитивные операции, основанные на регулярных выражениях: match проверяет соответствие только в начале строки, в то время как search проверяет соответствие в любом месте строки (это то, что делает Perl по умолчанию).

Обратите внимание, что match может отличаться от search даже при использовании регулярного выражения, начинающегося с '^': '^' соответствует только в начале строки или в режиме MULTILINE также сразу же после новой строки. Операция «match» преуспевает , только если шаблон совпадает в начале строки независимо от режима или в исходной позиции, заданной необязательным аргументом pos, независимо от того, предшествует ли эта строка новой строки .

Теперь достаточно разговоров. Время, чтобы увидеть пример кода:

# example code:
string_with_newlines = """something
someotherthing"""

import re

print re.match('some', string_with_newlines) # matches
print re.match('someother', 
               string_with_newlines) # won't match
print re.match('^someother', string_with_newlines, 
               re.MULTILINE) # also won't match
print re.search('someother', 
                string_with_newlines) # finds something
print re.search('^someother', string_with_newlines, 
                re.MULTILINE) # also finds something

m = re.compile('thing$', re.MULTILINE)

print m.match(string_with_newlines) # no match
print m.match(string_with_newlines, pos=4) # matches
print m.search(string_with_newlines, 
               re.MULTILINE) # also matches
360
ответ дан Vin 15 August 2018 в 17:25
поделиться
  • 1
    Как насчет строк, содержащих новые строки? – Daryl Spitzer 8 October 2008 в 02:01
  • 2
    даже со строками, содержащими новые строки, match () соответствует только в начале строки. – nosklo 8 October 2008 в 02:05
  • 3
    Почему бы кто-нибудь использовать ограниченный match, а не более общий search? это для скорости? – Alby 23 July 2014 в 03:55
  • 4
    @Alby соответствует намного быстрее, чем поиск, поэтому вместо выполнения regex.search («word») вы можете делать regex.match ((. *?) Word (. *?)) И получать тонны производительности, если вы работаете с миллионами образцов. – ivan_bilan 24 May 2016 в 09:34
  • 5
    Ну, это глупо. Зачем называть его match? Это умный маневр, чтобы засеять API с неинтуитивными именами, чтобы заставить меня прочитать документацию? Я все равно этого не сделаю! Бунтарь! – Sammaron 16 September 2016 в 15:14

Разница заключается в том, что re.match() вводит в заблуждение любого, кто привык к Perl , grep или sed регулярному выражению, а re.search() не. : -)

Более трезво, Как замечает Дж. Д. Кук , re.match() "ведет себя так, как если бы каждый шаблон имел предшествующий". Другими словами, re.match('pattern') равен re.search('^pattern'). Таким образом, он закрепляет левую сторону рисунка. Но он также не привязывает правую сторону паттерна: , которая все еще требует завершения $.

Честно говоря, я считаю, что re.match() должно быть устаревшим. Мне было бы интересно узнать причины, по которым его следует сохранить.

22
ответ дан CODE-REaD 15 August 2018 в 17:25
поделиться
  • 1
    «ведет себя так, как если бы каждый шаблон имел« добавленный ». & quot; это верно, только если вы не используете многострочный вариант. Правильное утверждение имеет «... имеет \ A preended & quot; – JoelFan 27 June 2017 в 23:38

re.match пытается сопоставить шаблон в начале строки. re.search пытается сопоставить шаблон по всей строке, пока не найдет совпадение.

14
ответ дан cschol 15 August 2018 в 17:25
поделиться

вы можете ссылаться на приведенный ниже пример, чтобы понять работу re.match и re.search

a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)

re.match не вернет none, но re.search вернет abc.

23
ответ дан ldR 15 August 2018 в 17:25
поделиться
  • 1
    Хотелось бы добавить, что поиск возвращает объект _sre.SRE_Match (или None, если не найден). Чтобы получить 'abc', вам нужно вызвать t.group () – SanD 1 March 2017 в 16:09

search & rArr; найти что-нибудь в строке и вернуть объект соответствия.

match & rArr; найти что-то в начале начала строки и вернуть объект соответствия.

60
ответ дан Ray Toal 15 August 2018 в 17:25
поделиться

match намного быстрее, чем поиск, поэтому вместо выполнения regex.search («word») вы можете делать regex.match ((. *?) word (. *?)) и набирать тонны производительности, если вы работаете с миллионами образцов.

Этот комментарий от @ivan_bilan в соответствии с принятым ответом выше заставил меня думать, если такой hack на самом деле ускоряя что-нибудь, поэтому давайте выясним, сколько тонн производительности вы действительно получите.

Я подготовил следующий набор тестов:

import random
import re
import string
import time

LENGTH = 10
LIST_SIZE = 1000000

def generate_word():
    word = [random.choice(string.ascii_lowercase) for _ in range(LENGTH)]
    word = ''.join(word)
    return word

wordlist = [generate_word() for _ in range(LIST_SIZE)]

start = time.time()
[re.search('python', word) for word in wordlist]
print('search:', time.time() - start)

start = time.time()
[re.match('(.*?)python(.*?)', word) for word in wordlist]
print('match:', time.time() - start)

Я сделал 10 измерений (1M, 2M, ..., 10M слов), что дало мне следующий график:

Полученные линии на удивление (на самом деле не так уж удивительно) прямолинейны. И функция search (немного) быстрее, учитывая эту конкретную комбинацию шаблонов. Мораль этого теста: Избегайте переопределения вашего кода.

5
ответ дан Solomon Ucko 15 August 2018 в 17:25
поделиться

re.search ищет шаблон по всей строке, тогда как re.match делает не поиск шаблона; если это не так, у него нет другого выбора, кроме как сопоставить его при начале строки.

46
ответ дан tzot 15 August 2018 в 17:25
поделиться
  • 1
    Зачем сочетаться в начале, но не до конца строки (fullmatch в python 3.4)? – Smit Johnth 14 July 2015 в 19:21
Другие вопросы по тегам:

Похожие вопросы: