Проверьте, существуют ли в тексте ключевые слова с одинаковым порядком - PullRequest
0 голосов
/ 13 января 2019

Итак, у нас есть два типа ключевых слов:

  1. Ключевые слова, которые начинаются с !, это ключевое слово должно содержаться в тексте
  2. Ключевые слова, которые начинаются с @!, это ключевое слово не должно отображаться в тексте

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

Пример 1: ключевые слова: ['! A', '! C'] Текст:

Multiline text ...

A

Some other text

C

Ожидаемый результат: True

Пример 2: ключевые слова: ['! A', '@! B', '! C'] Текст:

Multiline text ...

A

Some other text

B
C

Ожидаемый результат: Ложь, поскольку B находится между A и C

Пример 3: ключевые слова: ['! A', '@! B', '! C'] Текст:

Multiline text ...

A

Some other text

B

A

C

Ожидаемый результат: True, поскольку после второй A нет B, а после C -.

То, что я до сих пор пробовал (без удачи):

  1. Использовать регулярное выражение (я также не смог использовать отрицательный взгляд )
  2. Попробуйте написать для него рекурсивную функцию

Пример функции для метода 1:

def contain_keywords(content, keywords):
    content = str(content)
    regex_builder = []
    or_keyword = False
    for keyword in keywords:
        if keyword.startswith("@!"):
            reg = '[^%s]' % re.escape(keyword[2:])
            regex_builder.append(reg)
        elif keyword.startswith("!"):
            reg = '(%s)' % re.escape(keyword[1:])
            regex_builder.append(reg)

    pattern = r'.*%s.*' % ('([\s\S])*'.join(regex_builder))
    res = re.search(pattern, content)
    return res is not None

Пример функции для метода 2:

def contain_keywords2(content, keywords, offset=0, keyword_index=0):
    content = str(content)
    valid_pattern = True
    or_keyword = False

    if keyword_index >= len(keywords) or offset >= len(content):
        return True

    for keyword_index, keyword in enumerate(keywords[keyword_index:]):
        keyword = keyword.strip()
        if keyword.startswith("@!"):
            reg = keyword[2:]
            location = content[offset:].find(reg)
            if location != -1:
                return False
            valid_pattern = contain_keywords2(content, keywords, offset=offset, keyword_index=keyword_index+1)
            if not valid_pattern:
                return False
        elif keyword.startswith("!"):
            reg = keyword[1:]
            location = content[offset:].find(reg)
            print(location + offset)
            if location == -1:
                return False
            if keyword_index + 1 >= len(keywords):
                break
            valid_pattern = contain_keywords2(content, keywords, offset=offset + location + len(reg), keyword_index=keyword_index+1)
            if not valid_pattern:
                return False
    return valid_pattern

1 Ответ

0 голосов
/ 14 января 2019

Так как никто не ответил, я выложу свое решение:

def contain_keywords2(content_text, keywords, offset=0, keyword_index=0):

    or_keyword = False

    if keyword_index >= len(keywords) or offset >= len(content_text):
        return True

    for loop_keyword_index, keyword in enumerate(keywords[keyword_index:]):
        keyword = keyword.lstrip()
        if keyword.startswith("@!"):
            reg = keyword[2:]
            # Don't look whole file, just search it in at last 10 lines:
            # If you want to search all over the file, remove these 3 lines (including pos_of_tens_line at location ...)
            pos_of_tens_line = findnth(content_text[offset:], '\n', 10)
            if pos_of_tens_line == -1:
                pos_of_tens_line = len(content_text)

            location = content_text.find(reg, offset, offset + pos_of_tens_line)

            if location != -1:
                return False
            return contain_keywords2(content_text, keywords, offset=offset,
                                     keyword_index=keyword_index + loop_keyword_index + 1)
        elif keyword.startswith("!"):
            reg = keyword[1:].strip()

            for keyword_positions in list(find_all(content_text[offset:], reg)):
                valid_pattern = contain_keywords2(content_text, keywords,
                                                  offset=(offset + keyword_positions + len(reg)),
                                                  keyword_index=(keyword_index + loop_keyword_index + 1))
                if valid_pattern:
                    return True
            return False
        elif keyword.startswith('|!'):
            or_keyword = True
            break

    if or_keyword:
        for keyword in keywords:
            if keyword.startswith('|!'):
                if keyword[2:] in content_text:
                    return True
    return False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...