Шаблон регулярных выражений в Python для специальных символов

#python #regex #string

#python #регулярное выражение #строка

Вопрос:

Я задавал аналогичный вопрос несколько дней назад здесь, и это было большой помощью! Новая задача, которую я хотел создать, — это дальнейшее развитие шаблона регулярных выражений для поиска определенных форматов в этой итерации, и я думал, что решил ее, используя регулярное выражение 101 для сборки / тестирования кода регулярных выражений, но при применении в Python получил «шаблон, не содержащий группы». Ниже приведен тестовый df и изображение того, какими должны быть результаты / код, предоставленный через StackOverflow, который работал только с цифрами.

        
df = pd.DataFrame([["{1} | | Had a Greeter welcome clients {1.0}     | | Take measures to ensure a safe and organized distribution {1.000}         | | Protected confidentiality of clients (on social media, pictures, in conversation, own congregation members receiving assistance, etc.)",
                    "{1.00}  | | Chairs for clients to sit in while waiting {1.0000}     | | Take measures to ensure a safe and organized distribution"],
                   ["{1  } | Financial literacy/budgeting {1   } | | Monetary/Bill Support {1}    | | Mental Health Services/Counseling",
                    "{1}| | Clothing Assistance {1       }  | | Healthcare {1}    | | Mental Health Services/Counseling {1}     | | Spiritual Support {1}      | | Job Skills Training"]
                    ] , columns = ['CF1', 'CF2'])
 

Результат

Вот код итерации, который работал только с цифрами. Я изменил поиск по шаблону на свой новый шаблон регулярных выражений, и он не сработал.

Исходный код: (df.stack().str.extractall('(d )')[0] .groupby(level=[0,1]).sum().unstack())

Новый код (не удалось распознать шаблон): (df.stack().str.extractall(r'(?<={)[d . ] (?=})')[0].astype(int) .groupby(level=[0,1]).sum().unstack())

** В тестовом df вы увидите, что я хочу записывать только числа между «{}», и после числа, которое я хочу записать и суммировать, есть смесь десятичных знаков и пробелов. Новый шаблон не работал в приложении, поэтому любая помощь была бы отличной! **

Ответ №1:

Ваше (?<={)[d . ] (?=}) регулярное выражение не содержит групп захвата Series.str.extractall , в то время как для вывода значения требуется хотя бы одна группа захвата.

Вам нужно использовать

 (df.stack().str.extractall(r'{s*(d (?:.d )?)s*}')[0].astype(float) .groupby(level=[0,1]).sum().unstack())
 

Вывод:

    CF1  CF2
0  3.0  2.0
1  3.0  5.0
 

Регулярное {s*(d (?:.d )?)s*} выражение соответствует

  • { { символ
  • s* — ноль или более пробелов
  • (d (?:.d )?) — Группа 1 (обратите внимание, что захваченное значение этой группы будет выводом extractall метода, для этого требуется хотя бы одна группа захвата): одна или несколько цифр, а затем необязательное вхождение a . и одной или нескольких цифр
  • s* — ноль или более пробелов
  • } } символ.

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

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

1. Спасибо @Wiktor! Это работает отлично! Мне нужно будет выяснить, почему мой исходный код регулярных выражений не работал в приложении

2. @BeginnerProgrammer Смотрите начало моего ответа. Кроме того, (?<={)[d . ] (?=}) просто соответствует одному или нескольким , . , пробелам или цифрам сразу после { и непосредственно перед } . Таким образом, он может даже «поймать» ... {...} .

3. @Witkor. Это долгий путь, так как прошло некоторое время с тех пор, как вы говорили в последний раз, но это решение сработало! Однако я надеялся улучшить свои результаты, изменив эту группу на основе двух столбцов, и столкнулся с проблемой, из-за которой она не распознает имена столбцов. Какие изменения требуются в этом заявлении groupby, которое вы предоставили. Моими столбцами являются [‘SubID’, ‘Labels’] .

4. @BeginnerProgrammer Извините, что отвечаю так поздно, но, похоже, вы хотите df2 = df[['subID', 'Labels']] , а затем (df2.stack().str.extractall(r'{s*(d (?:.d )?)s*}')[0].astype(float) .groupby(level=[0,1]).sum().unstack())

Ответ №2:

Вы можете использовать '{([d.] )}' :

 (df.stack().str.extractall(r'{([d.] )}')[0]
   .astype(float).groupby(level=[0,1]).sum().unstack())
 

вывод:

    CF1  CF2
0  3.0  2.0
1  1.0  4.0
 
только как int:
 (df.stack().str.extractall(r'{(d )(?:.d )?}')[0]
   .astype(int).groupby(level=[0,1]).sum().unstack())
 

вывод:

    CF1  CF2
0    3    2
1    1    4
 

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

1. Еще раз спасибо @Mozay! Не могли бы вы объяснить, почему формат отличается от того, который работал в регулярном выражении 101? Также возможно ли включить пробел, поскольку некоторые из «{1}» имеют пробелы в формате другого типа

2. Да, вы можете добавить s* -> '{(d )(?:.d )?s*}'

3. Это долгий путь, так как прошло много времени с тех пор, как вы говорили в последний раз, но вы помогли мне решить предыдущие проблемы с регулярными выражениями, такие как это. Я надеялся улучшить свои результаты, изменив эту группу на основе двух столбцов в исходном df и столкнулся с проблемой, из-за которой он не распознал имена столбцов. Какие изменения требуются в этом операторе groupby? Моими столбцами являются [‘SubID’, ‘Labels’] .