Получение первого слова после специального символа в строке в Python - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть несколько таких строк:

s='@VirginAmerica it was amazing, and arrived an hour early.'
t='heyyyyy@VirginAmerica , am I dreaming?'
m='heyyyyy @VirginAmerica , am I dreaming?'
u=''
f='@United...'
h='@United@VirginAmerica'

Я хочу вынуть слово после @ в кадре данных и удалить это слово из его кадра данных.теперь я использую это для выведения первого слова после @, но результат не является правильным во всех строках.

s.split(' ', 1)[0]==>correct==>VirginAmerica
t.split(' ', 1)[0]==>wrong==>heyyyyy@VirginAmerica==>'VirginAmerica' is correct 
m.split(' ', 1)[0]==>correct==>VirginAmerica
u.split(' ', 1)[0]==>correct==>''
f.split(' ', 1)[0]==>wrong==>@United...==>'United' is correct
h.split(' ', 1)[0]==>wrong==>@United@VirginAmerica==>I just want the first one

и для удаления слова после @ и записи всей строки без @ и слова,Я получу это:

s.split(' ', 1)[1]==>correct==>it was amazing, and arrived an hour early.
t.split(' ', 1)[1]==>wrong==>@VirginAmerica , am I dreaming?==>'heyyyyy , am I dreaming?' is correct 
m.split(' ', 1)[1]==>wrong==>@VirginAmerica , am I dreaming?==>VirginAmerica==>'heyyyyy , am I dreaming?' is correct
u.split(' ', 1)[1]==>wrong==>IndexError: list index out of range==> ''is correct
f.split(' ', 1)[1]==>wrong==>IndexError: list index out of range==>'...' is correct
h.split(' ', 1)[1]==>wrong==>IndexError: list index out of range==>'@VirginAmerica' is correct

Не могли бы вы помочь мне с этой проблемой?было бы лучше не использовать какую-либо библиотеку.но если это единственный выбор, это нормально.

Спасибо

Ответы [ 3 ]

0 голосов
/ 05 февраля 2019

Вот ваш код с тестами

import re

s='@VirginAmerica it was amazing, and arrived an hour early.'
t='heyyyyy@VirginAmerica , am I dreaming?'
m='heyyyyy @VirginAmerica , am I dreaming?'
u=''
f='@United...'
h='@United@VirginAmerica'

def find_match(str):
  res = re.search('@(\w+)', str)
  if not res:
    return ''
  return res.group(1)

def sub_match(str):
  return re.sub('^[^@]*@\w+', '', str)

assert find_match(s) == 'VirginAmerica'
assert find_match(t) == 'VirginAmerica'
assert find_match(m) == 'VirginAmerica'
assert find_match(u) == ''
assert find_match(f) == 'United'
assert find_match(h) == 'United'

assert sub_match(s) == ' it was amazing, and arrived an hour early.'
assert sub_match(t) == ' , am I dreaming?'
assert sub_match(m) == ' , am I dreaming?'
assert sub_match(u) == ''
assert sub_match(f) == '...'
assert sub_match(h) == '@VirginAmerica'

find_match (str)

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

Мы ищем первое слово, котороеначинается со знака @.Это легко описать с помощью следующего регулярного выражения

=> @\w+

, где @ означает совпадение с точным символом, а \w+ совпадение с 1 или более символами слова (объяснение документа дляэто) .

А также мы используем (), чтобы выбрать результирующую группу, так как нам нужно слово без @, мы заключаем \w+ только

=> @(\w+)

sub_match (str)

Он использует ту же идею для регулярного выражения, но это немного сложнее из-за случая с первым соответствием @ символа.

Для этого сначала мы сопоставляем все символы, которые не являются @ -> [^@]* частью регулярного выражения, а затем мы используем то же регулярное выражение, которое мы использовали в find_match(str), но без группы, поскольку нам просто нужнозаменить все это на @.

PS Ссылка для запуска кода в сети https://repl.it/repls/SinfulWhichSynergy Здесь вы можете проверить свои регулярные выражения на Python и попрактиковаться с

0 голосов
/ 05 февраля 2019

В этом ответе просто используются простые функции python, и он пытается не быть «pythonic», поскольку это может сбить с толку новичков.

В основном он ищет @ в предложении с sentence.find('@'), чтовозвращает индекс местоположения первого вхождения '@' или -1.Одна из вещей, не упомянутых в вопросе OP, - это то, что составляет «@word» - более важно , где он останавливается .Я добавил константу WORD_END для хранения всех букв, обозначающих конец слова.Таким образом, функция находит «@word» от первого @ и до первого символа в WORD_END.

Еще один момент, на который следует обратить внимание, это то, что нет тестового примера, в котором нет '@ 'в предложении.

#! /usr/bin/env python3

TESTS=['@VirginAmerica it was amazing, and arrived an hour early',
        'heyyyyy@VirginAmerica , am I dreaming?',
        'heyyyyy @VirginAmerica , am I dreaming?',
        '',
        '@United...',
        '@United@VirginAmerica',
        'no-at-word' ]

def removeMarkedWords(sentence):
    # A word ends with
    WORD_END=' \t\r\n,.;:<>?/+!@#$%^&*()|\}][{\"\'='
    result = ''

    # is there an @word?
    at_location = sentence.find('@')
    if ( at_location == -1 ):
        result = sentence
    else:
        while ( at_location != -1 ):
            if ( at_location > 0 ):
                result += sentence[0:at_location]  # keep the sentence prefix (before the '@')
                sentence = sentence[at_location:]  # remove the prefix
            else:
                # The sentence begins '@something...'
                # Find the end of the @word by finding the first non-word letter
                index = 1
                while ( index < len(sentence) and sentence[index] not in WORD_END ):
                    index += 1
                # trim off the @word (and throw it away)
                sentence = sentence[index:]
                #print( "DEBUG sentence = [" + sentence + "]" )
            # is there another @word?
            at_location = sentence.find('@')
            if ( at_location == -1 ):
                result += sentence  # no more @words, just keep the tail
    return result


for test in TESTS:
    print( "[%s]->[%s]" % ( test, removeMarkedWords( test ) ) )

Дать результат:

[@VirginAmerica it was amazing, and arrived an hour early]->[ it was amazing, and arrived an hour early]
[heyyyyy@VirginAmerica , am I dreaming?]->[heyyyyy , am I dreaming?]
[heyyyyy @VirginAmerica , am I dreaming?]->[heyyyyy  , am I dreaming?]
[]->[]
[@United...]->[...]
[@United@VirginAmerica]->[]
[no-at-word]->[no-at-word]
0 голосов
/ 05 февраля 2019

Другая реализация, использующая регулярное выражение, получает слово, следующее за @ из строки.

import re

s='@VirginAmerica it was amazing, and arrived an hour early.'
t='heyyyyy@VirginAmerica , am I dreaming?'
m='heyyyyy @VirginAmerica , am I dreaming?'
u=''
f='@United...'
h='@United@VirginAmerica'

for text in [s, t, m, u, f, h]:
    print(re.findall(r'@(\w+)', text))

печатает

['VirginAmerica ']
['VirginAmerica ']
['VirginAmerica ']
[]
['United']
['United', 'VirginAmerica']

Также приятно отметить, re - это стандартная библиотека Python, поэтому вы не используете ничего, что уже не включено в Python.

Если вы не хотите использовать регулярное выражение, вы можете использовать split еще, но что-то подобное приведет кто же самое, что и выше:

s='@VirginAmerica it was amazing, and arrived an hour early.'
t='heyyyyy@VirginAmerica , am I dreaming?'
m='heyyyyy @VirginAmerica , am I dreaming?'
u=''
f='@United...'
h='@United@VirginAmerica'

for text in [s, t, m, u, f, h]:
    _, *words = text.split('@')
    print([words.split()[0] for word in words])

Редактировать

Согласно вашему комментарию, чтобы получить первое вхождение слова, следующего за @, например, первое слово'united' в h просто используйте нарезку списка (просто убедитесь, что хотя бы одно слово соответствует регулярному выражению, в противном случае используйте попытку, кроме блока)

h='@United@VirginAmerica'
re.sub(r'@(\w+)' h)[0]
#United

Чтобы получить слово без первого вхождения @word, используйте sub Я также добавил пробел и знак вопроса после него, чтобы убрать пробел, чтобы он выглядел правильно при печати. (если вы хотите напечатать все удаленные вхождения, просто удалите count из этого метода)

s='@VirginAmerica it was amazing, and arrived an hour early.'
re.sub(r'@(\w+) ?', '', s, count=1)
#it was amazing, and arrived an hour early.

У меня есть все, что я сделал в repl.it .это попытка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...