python - هل لدى بايثون طريقة سلسلة "تحتوي على" سلسلة فرعية؟




string substring contains (13)

أنا أبحث عن string.contains أو string.indexof في بايثون.

اريد ان افعل:

if not somestring.contains("blah"):
   continue

Answers

إذا كنت راضيًا عن كلمة "blah" in somestring ولكنك تريدها أن تكون عبارة عن مكالمة وظيفية ، فيمكنك القيام بذلك على الأرجح

import operator

if not operator.contains(somestring, "blah"):
    continue

يمكن العثور على جميع المشغلين في Python بشكل أو بآخر في وحدة المشغل بما in ذلك.


لذلك على ما يبدو لا يوجد شيء مماثل للمقارنة ناقلات. طريقة بيثون واضحة للقيام بذلك هي:

names = ['bob', 'john', 'mike']
any(st in 'bob and john' for st in names) 
>> True

any(st in 'mary and jane' for st in names) 
>> False

if needle in haystack: هو الاستخدام العادي ، كما يقولMichael - فإنه يعتمد على المشغل ، وأكثر قابلية للقراءة وأسرع من استدعاء الأسلوب.

إذا كنت حقا بحاجة إلى طريقة بدلا من المشغل (على سبيل المثال للقيام ببعض key= غريب key= لفرز غريب جدا ...؟) ، من شأنه أن يكون 'haystack'.__contains__ . ولكن منذ المثال الخاص بك هو للاستخدام في ، if كنت لا تعني حقا ما تقوله ؛-). ليس من الشكل الجيد (ولا يمكن قراءته ، ولا يتسم بالكفاءة) استخدام أساليب خاصة مباشرة - بل يتم استخدامها بدلاً من ذلك من خلال المشغلين والمبتكرين الذين يفوضونهم.


طريقة أخرى لمعرفة ما إذا كانت سلسلة تحتوي على بضعة أحرف أم لا مع قيمة إرجاع Boolean (أي True أو `False):

str1 = "This be a string"
find_this = "tr"
if find_this in str1:
    print find_this, " is been found in ", str1
else:
    print find_this, " is not found in ", str1

إذا كانت مجرد بحث عن سلسلة فرعية ، يمكنك استخدام string.find("substring") .

عليك أن تكون حذراً قليلاً في find ، index ، وعلى الرغم من أنها عمليات البحث الفرعية. بعبارة أخرى ، هذا:

s = "This be a string"
if s.find("is") == -1:
    print "No 'is' here!"
else:
    print "Found 'is' in the string."

ستطبع Found 'is' in the string. وبالمثل ، if "is" in s: سيتم تقييمه إلى True . هذا قد يكون أو لا يكون ما تريده.


يوجد في بيثون طريقتان بسيطتان يمكنك تحقيقهما:

الطريقة البايثونية: استخدام كلمة "في" في بيثون

in يأخذ "جهازي" اثنين ، أحدهما على اليسار ( السلسلة الفرعية ) والآخر على اليمين ، ويعرض True إذا كانت الوسيطة اليمنى متضمنة في وسيطة الحقوق ، وإذا لم يكن الأمر كذلك ، فإنها تُرجع False .

example_string = "This is an example string"
substring = "example"
print(substring in example_string)

انتاج:

True

الطريقة غير البيثونية: استخدام str.find في Python:

ترجع طريقة find موضع السلسلة داخل السلسلة أو -1 إذا لم يتم العثور عليها. ولكن ببساطة تحقق ما إذا كان الموقف ليس -1.

if example_string.find(substring) != -1:
    print('Substring found!')
else:
    print('Substring not found!')

انتاج:

Substring found!

هنا إجابتك:

if "insert_char_or_string_here" in "insert_string_to_search_here":
    #DOSTUFF

للتحقق مما إذا كانت خاطئة:

if not "insert_char_or_string_here" in "insert_string_to_search_here":
    #DOSTUFF

أو:

if "insert_char_or_string_here" not in "insert_string_to_search_here":
    #DOSTUFF

لا ، لا توجد أي string.contains(str) ، ولكن هناك عامل التشغيل:

if substring in someString:
    print "It's there!!!"

هذا مثال عمل أكثر تعقيدًا:

# Print all files with dot in home directory
import commands
(st, output) = commands.getstatusoutput('ls -a ~')
print [f for f in output.split('\n') if '.' in f ]

إذا كنت تبحث عن البحث غير الحساس لحالة الأحرف ككل ، بدلاً من سلسلة فرعية موجودة في كلمة أخرى:

import string

s = 'This is my text example'
if 'is' not in (word.lower() 
    for split_char in string.punctuation + string.whitespace 
    for word in s.split(split_char)):
    # do something

هل يحتوي Python على سلسلة تحتوي على طريقة فرعية؟

نعم ، لكن لدى Python مشغل مقارنة يجب استخدامه بدلاً من ذلك ، لأن اللغة تقصد استخدامه ، ويتوقع منك المبرمجون الآخرون استخدامه. هذه الكلمة الرئيسية موجودة ، والتي يتم استخدامها كمشغل للمقارنة:

>>> 'foo' in '**foo**'
True

والعكس (الملحق) ، الذي يطرحه السؤال الأصلي ، not in :

>>> 'foo' not in '**foo**' # returns False
False

هذا هو لغويا نفس not 'foo' in '**foo**' ولكنه أكثر قابلية للقراءة ومقدّ م بشكل صريح في اللغة كتحسين للقراءة.

تجنب استخدام __contains__ ، find ، index

كما هو موعود ، إليك الطريقة التي contains :

str.__contains__('**foo**', 'foo')

يعود True . يمكنك أيضًا استدعاء هذه الوظيفة من مثيل الأوتار الفائقة:

'**foo**'.__contains__('foo')

لكن لا تفعل تعتبر الطرق التي تبدأ بشرط سفلية شرطية خاصة. السبب الوحيد لاستخدام هذا هو عند توسيع الوظيفة not in الوظيفة (على سبيل المثال ، إذا كانت الفئة الفرعية subclassing str ):

class NoisyString(str):
    def __contains__(self, other):
        print('testing if "{0}" in "{1}"'.format(other, self))
        return super(NoisyString, self).__contains__(other)

ns = NoisyString('a string with a substring inside')

و الأن:

>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True

أيضاً ، تجنب الأساليب سلسلة التالية:

>>> '**foo**'.index('foo')
2
>>> '**foo**'.find('foo')
2

>>> '**oo**'.find('foo')
-1
>>> '**oo**'.index('foo')

Traceback (most recent call last):
  File "<pyshell#40>", line 1, in <module>
    '**oo**'.index('foo')
ValueError: substring not found

قد لا تحتوي اللغات الأخرى على طرق للاختبار المباشر للخطوط الفرعية ، ولذلك سيكون عليك استخدام هذه الأنواع من الأساليب ، ولكن باستخدام Python ، يكون استخدام معالج المقارنة أكثر فاعلية.

مقارنات الأداء

يمكننا مقارنة طرق مختلفة لتحقيق الهدف نفسه.

import timeit

def in_(s, other):
    return other in s

def contains(s, other):
    return s.__contains__(other)

def find(s, other):
    return s.find(other) != -1

def index(s, other):
    try:
        s.index(other)
    except ValueError:
        return False
    else:
        return True



perf_dict = {
'in:True': min(timeit.repeat(lambda: in_('superstring', 'str'))),
'in:False': min(timeit.repeat(lambda: in_('superstring', 'not'))),
'__contains__:True': min(timeit.repeat(lambda: contains('superstring', 'str'))),
'__contains__:False': min(timeit.repeat(lambda: contains('superstring', 'not'))),
'find:True': min(timeit.repeat(lambda: find('superstring', 'str'))),
'find:False': min(timeit.repeat(lambda: find('superstring', 'not'))),
'index:True': min(timeit.repeat(lambda: index('superstring', 'str'))),
'index:False': min(timeit.repeat(lambda: index('superstring', 'not'))),
}

والآن نرى أن استخدامه هو أسرع بكثير من الآخرين. أقل وقت للقيام بعملية مكافئة أفضل:

>>> perf_dict
{'in:True': 0.16450627865128808,
 'in:False': 0.1609668098178645,
 '__contains__:True': 0.24355481654697542,
 '__contains__:False': 0.24382793854783813,
 'find:True': 0.3067379407923454,
 'find:False': 0.29860888058124146,
 'index:True': 0.29647137792585454,
 'index:False': 0.5502287584545229}

يمكنك استخدام المشغل :

if "blah" not in somestring: 
    continue

in سلاسل بيثون والقوائم

إليك بعض الأمثلة المفيدة التي تتحدث عن نفسها فيما يتعلق بالطريقة:

"foo" in "foobar"
True

"foo" in "Foobar"
False

"foo" in "Foobar".lower()
True

"foo".capitalize() in "Foobar"
True

"foo" in ["bar", "foo", "foobar"]
True

"foo" in ["fo", "o", "foobar"]
False

مذكرة قانونية. القوائم عبارة عن تكرارات ، والأسلوب يعمل على التكرار ، وليس فقط السلاسل.


إجابة متوافقة

نظرًا لوجود العديد من الإجابات باستخدام ميزات Bash الخاصة ، فهناك طريقة للعمل تحت الأصداف ذات busybox ، مثل busybox :

[ -z "${string##*$reqsubstr*}" ]

في الممارسة العملية ، قد يعطي هذا:

string='echo "My string"'
for reqsubstr in 'o "M' 'alt' 'str';do
  if [ -z "${string##*$reqsubstr*}" ] ;then
      echo "String '$string' contain substring: '$reqsubstr'."
    else
      echo "String '$string' don't contain substring: '$reqsubstr'."
    fi
  done

تم اختبار ذلك تحت bash و dash و ksh و ash (busybox) وكانت النتيجة دائمًا:

String 'echo "My string"' contain substring: 'o "M'.
String 'echo "My string"' don't contain substring: 'alt'.
String 'echo "My string"' contain substring: 'str'.

في وظيفة واحدة

كما تم السؤال عنEeroAaltonen هنا هو نسخة من نفس العرض التجريبي ، تم اختباره تحت نفس القذائف:

myfunc() {
    reqsubstr="$1"
    shift
    string="[email protected]"
    if [ -z "${string##*$reqsubstr*}" ] ;then
        echo "String '$string' contain substring: '$reqsubstr'.";
      else
        echo "String '$string' don't contain substring: '$reqsubstr'." 
    fi
}

ثم:

$ myfunc 'o "M' 'echo "My String"'
String 'echo "My String"' contain substring 'o "M'.

$ myfunc 'alt' 'echo "My String"'
String 'echo "My String"' don't contain substring 'alt'.

ملاحظة: يجب عليك الهروب أو وضع علامات اقتباس مزدوجة و / أو علامات اقتباس مزدوجة:

$ myfunc 'o "M' echo "My String"
String 'echo My String' don't contain substring: 'o "M'.

$ myfunc 'o "M' echo \"My String\"
String 'echo "My String"' contain substring: 'o "M'.

وظيفة بسيطة

تم اختبار ذلك ضمن busybox ، dash ، وبالطبع bash :

stringContain() { [ -z "${2##*$1*}" ]; }

هذا كل ما لدي أيها الناس!

ثم الآن:

$ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi
no
$ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi
yes

... أو إذا كانت السلسلة المقدمة فارغة ، كما أشارSjlver ، فستصبح الوظيفة:

stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }

أو كما اقترحه تعليق Adrian Günter ، وتجنب switche -o :

stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ] ;} ; }

مع سلاسل فارغة:

$ if stringContain '' ''; then echo yes; else echo no; fi
yes
$ if stringContain 'o "M' ''; then echo yes; else echo no; fi
no




python string substring contains