Как проверить строку на наличие определенных символов? [закрыто]


182

Как я могу проверить, содержит ли строка несколько определенных символов, используя Python 2?

Например, с учетом следующей строки:

Преступники украли драгоценности на 1 000 000 долларов.

Как определить, есть ли у него знаки доллара ("$"), запятые (",") и цифры?


1
Означает ли это, что каждый символ должен быть одним из них, или достаточно, чтобы один (или все) из этих символов присутствовал в строке? Должны ли они быть в каком-то порядке (например, $ 2,00), чтобы он был действительным?
NullUserException

2
Так же, как и другой подход, not set(p).isdisjoint(set("0123456789$,"))где pнаходится строка для тестирования.
Кевин

Ответы:


265

Предполагая, что ваша строка s:

'$' in s        # found
'$' not in s    # not found

# original answer given, but less Pythonic than the above...
s.find('$')==-1 # not found
s.find('$')!=-1 # found

И так далее для других персонажей.

... или

pattern = re.compile(r'\d\$,')
if pattern.findall(s):
    print('Found')
else
    print('Not found')

... или

chars = set('0123456789$,')
if any((c in chars) for c in s):
    print('Found')
else:
    print('Not Found')

[Редактировать: добавил '$' in sответы]


20
s.find('$')!=-1=> '$' in s:-)
Йохен Ритцель

Есть ли какая-то конкретная причина, почему значение на not found было -1, а не 0 ??
akki

2
@akki not found равно -1, потому что 0 - это индекс первого символа в строке. Таким образом, «abc» .find ('a') = 0. Было бы неоднозначно, если бы 0 было также не найденным значением.
lemiant

1
Мне нравится эта последняя версия с использованием any(). Есть ли способ сослаться на найденный символ cв питоническом стиле (кажется, что он ограничен any()только внутри ), или мне нужно сделать поиск нескольких символов более явным?
Дженс

3
Второй пример не работает: регулярное выражение должно иметь квадратные скобки, r'[\d\$,]'чтобы оно соответствовало любому из этих символов, и else:в конце отсутствует двоеточие.
Bjnord

23

Пользователь Jochen Ritzel сказал об этом в комментарии к ответу на этот вопрос от пользователя dappawit. Он должен работать:

('1' in var) and ('2' in var) and ('3' in var) ...

«1», «2» и т. Д. Следует заменить теми символами, которые вы ищете.

См. Эту страницу в документации по Python 2.7 для получения дополнительной информации о строках, в том числе об использовании inоператора для тестов подстрок.

Обновление: это делает ту же работу, что и мое предложение с меньшим количеством повторений:

# When looking for single characters, this checks for any of the characters...
# ...since strings are collections of characters
any(i in '<string>' for i in '123')
# any(i in 'a' for i in '123') -> False
# any(i in 'b3' for i in '123') -> True

# And when looking for subsrings
any(i in '<string>' for i in ('11','22','33'))
# any(i in 'hello' for i in ('18','36','613')) -> False
# any(i in '613 mitzvahs' for i in ('18','36','613')) ->True

+1 это более компактно, чем множественные .find (), и хорошо, если количество искомых символов мало. Не нужны скобки, хотя.
Шон

1
@Sean О скобках: я знаю, однако мне легче всегда их использовать, чем всегда помнить порядок старшинства :-).
Аббафей

11

Быстрое сравнение времени в ответе на пост Аббафей:

import timeit

def func1():
    phrase = 'Lucky Dog'
    return any(i in 'LD' for i in phrase)

def func2():
    phrase = 'Lucky Dog'
    if ('L' in phrase) or ('D' in phrase):
        return True
    else:
        return False

if __name__ == '__main__': 
    func1_time = timeit.timeit(func1, number=100000)
    func2_time = timeit.timeit(func2, number=100000)
    print('Func1 Time: {0}\nFunc2 Time: {1}'.format(func1_time, func2_time))

Вывод:

Func1 Time: 0.0737484362111
Func2 Time: 0.0125144964371

Так что код более компактен с любым, но быстрее с условным.


РЕДАКТИРОВАТЬ: TL; DR - Для длинных строк, если-то все еще намного быстрее, чем любой!

Я решил сравнить время для длинной случайной строки, основываясь на некоторых правильных моментах, поднятых в комментариях:

# Tested in Python 2.7.14

import timeit
from string import ascii_letters
from random import choice

def create_random_string(length=1000):
    random_list = [choice(ascii_letters) for x in range(length)]
    return ''.join(random_list)

def function_using_any(phrase):
    return any(i in 'LD' for i in phrase)

def function_using_if_then(phrase):
    if ('L' in phrase) or ('D' in phrase):
        return True
    else:
        return False

if __name__ == '__main__':
    random_string = create_random_string(length=2000)
    func1_time = timeit.timeit(stmt="function_using_any(random_string)",
                               setup="from __main__ import function_using_any, random_string",
                               number=200000)
    func2_time = timeit.timeit(stmt="function_using_if_then(random_string)",
                               setup="from __main__ import function_using_if_then, random_string",
                               number=200000)
    print('Time for function using any: {0}\nTime for function using if-then: {1}'.format(func1_time, func2_time))

Вывод:

Time for function using any: 0.1342546
Time for function using if-then: 0.0201827

Если-то почти на порядок быстрее любого!


1
именно то, что я хотел знать :-)
Ларс

1
Кто-нибудь может объяснить, почему условное выражение намного быстрее, чем любое другое?
Джош

@ Джош, наверное, потому что все проще. Func1 использует расширенное понимание списков, поэтому он автоматически становится сложнее для простых вещей. Но для 1000 символов вполне может быть быстрее использовать Func1
Hack5

@ Hack5 предположим, phraseчто строка с алфавитами от A до Z, и я хочу напечатать, какие алфавиты отсутствуют в строке вместе будет any()лучше? или есть какой-нибудь короткий способ проверить?
Авишек Датта Рэй

@Barefaced Голый на таком уровне, выбирай тот, который выглядит лучше. Скорость, вероятно, не имеет значения, если вы не контролируете ядерное оружие (в этом случае вы не должны использовать python)
Hack5

5

Это проверит, состоят ли строки из некоторой комбинации или цифр, знака доллара и запятых. Это то, что вы ищете?

импорт ре

s1 = 'Тестовая строка'
s2 = '1234,12345 $'

regex = re.compile ('[0-9, $] + $')

if (regex.match (s1)):
   печать "s1 matched"
еще:
   вывести «s1 не совпадает»

if (regex.match (s2)):
   печать "s2 matched"
еще:
   печать "s2 не соответствует"

Вам не нужно экранировать символ $, если он находится в классе символов. Также это будет соответствовать 'testing $tring', что я не думаю, что ОП хочет, чтобы это произошло.
NullUserException

Если я правильно помню, это не будет соответствовать, 'testing $tring'если matchметод используется, только если searchиспользуется. Поэтому я думаю, что его код в порядке.
dappawit

@dappa Это будет по- прежнему соответствовать '$string'хотя
NullUserException

-2
s=input("Enter any character:")   
if s.isalnum():   
   print("Alpha Numeric Character")   
   if s.isalpha():   
       print("Alphabet character")   
       if s.islower():   
         print("Lower case alphabet character")   
       else:   
         print("Upper case alphabet character")   
   else:   
     print("it is a digit")   
elif s.isspace():   
    print("It is space character")   

еще:
печать («Не пробел специальный символ»)


1
Не могли бы вы предоставить немного больше контекста для вашего ответа.
медная обезьяна

проверка типа символов, присутствующих в строке: isalnum (): возвращает True, если все символы буквенно-цифровые (от a до z, от A до Z, от 0 до 9) isalpha (): возвращает True, если все символы являются только символами алфавита (от a до z, От A до Z), isdigit (): возвращает True, если все символы только цифры (от 0 до 9) islower (): возвращает True, если все символы являются символами алфавита нижнего регистра isupper (): возвращает True, если все символы являются символами алфавита верхнего регистра istitle (): возвращает True, если строка в заглавии case isspace (): возвращает True, если строка содержит только пробелы @LazerBass
Nagaraj
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.