Как сопоставить и заменить все после определенного слова, пока оно не достигнет запятой в списке строк с использованием python?

#python #regex #string

Вопрос:

У меня есть фрейм данных со списком строк, как показано ниже

 df

text
,info_concern_blue,replaced_mod,replaced_rad
,info_concern,info_concern_red,replaced_unit
,replaced_link
 

Я хочу заменить все слова после info_concern, например. info_concern_blue/info_concern_red для info_concern, пока не встретится запятая.

Я попробовал следующее регулярное выражение:

 df['replaced_text'] =  [re.sub(r'info_concern[^,]*. ?,', 'info_concern,',
           x) for x in df['text']]
 

Но это дает мне неправильные результаты.

Желаемый результат:

 replaced_text

    ,info_concern,replaced_mod,replaced_rad
    ,info_concern,info_concern,replaced_unit
    ,replaced_link
 

Пожалуйста, предложите/посоветуйте.

Комментарии:

1. Если он встретит запятую, я хочу, чтобы он перестал совпадать дальше.

Ответ №1:

Вы можете использовать

 df['replaced_text'] = df['text'].str.replace(r'(info_concern)[^,]*', r'1', regex=True)
 

Смотрите демонстрацию регулярных выражений.

Если вы хотите убедиться, что совпадение начинается сразу после запятой или начала строки, добавьте (?<![^,]) указатель в начале шаблона:

 df['replaced_text'] = df['text'].str.replace(r'(?<![^,])(info_concern)[^,]*', r'1', regex=True)
 

Смотрите эту демонстрацию регулярных выражений. Подробные сведения:

  • (?<![^,]) — прямо перед этим должно быть либо , или начало строки
  • (info_concern) — Группа 1: info_concern строка
  • [^,]* — ноль или более символов, отличных от запятой.

1 Замена заменяет совпадение значением группы 1.

Ответ №2:

Проблема в том, что шаблон info_concern[^,]*. ?, совпадает до первой запятой с использованием [^,]*

Затем эта часть . ?, соответствует по крайней мере одному символу (который также может быть запятой из-за . ), а затем до следующей первой запятой.

Поэтому, если есть вторая запятая, она будет совпадать и удалит слишком много.


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

Если справа должна быть запятая, вы можете это утверждать.

 (?<=binfo_concern)[^,]*(?=,)
 

Шаблон совпадает:

  • (?<=binfo_concern) Позитивный взгляд назад, утверждение info_concern слева
  • [^,]* Сопоставьте 0 раз любой символ, кроме ,
  • (?=,) Позитивный взгляд, утверждайте , прямо направо

Демонстрация регулярных выражений

Если запятая не является обязательной, вы можете опустить заголовок

 (?<=binfo_concern)[^,]*
 

Например

 import pandas as pd

texts = [
    ",info_concern_blue,replaced_mod,replaced_rad",
    ",info_concern,info_concern_red,replaced_unit",
    ",replaced_link"
]

df = pd.DataFrame(texts, columns=["text"])
df['replaced_text'] = df['text'].str.replace(r'(?<=binfo_concern)[^,]*(?=,)', '', regex=True)

print(df)
 

Выход

                                            text                             replaced_text
0  ,info_concern_blue,replaced_mod,replaced_rad   ,info_concern,replaced_mod,replaced_rad
1  ,info_concern,info_concern_red,replaced_unit  ,info_concern,info_concern,replaced_unit
2                                ,replaced_link                            ,replaced_link