регулярное выражение: удалите нули в середине строки (но сохраните единицы в конце) pyspark

#python #regex #apache-spark #pyspark

#python #регулярное выражение #apache-spark #pyspark

Вопрос:

Мне нужно удалить нули, которые находятся в середине строки, сохранив те, что в конце (в pyspark). Пока я нашел только регулярное выражение, которое удаляет начальные или конечные нули. Пример:

 df1 = spark.createDataFrame(
[
    ("GH0786",),
    ("HH7040",),
    ("IP0090",),
    ("AH567",),
],
["number"]
)
  

ВВОД:

  ------- 
|number |
 ------- 
|GH0786 |
|HH7040 |
|IP0090 |
|AH567  |
 ------- 
  

ОЖИДАЕМЫЙ РЕЗУЛЬТАТ:

  ------- 
|number |
 ------- 
|GH786  |
|HH740  |
|IP90  |
|AH567  |
 ------- 
  

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

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

1. https://regex101.com / — отличный сайт, где вы можете создавать и тестировать регулярные выражения — я полагаю, что в итоге у вас может получиться что-то вроде этого: r"(?<=.)(0 )(?=.)"

2. Пример «IP0090» кажется неправильным, согласно вашему вопросу, это должно быть «IP009», а не «IP900»

Ответ №1:

Вы можете использовать 0 (?!$) для сопоставления нулей, которых нет в конце строк; ?! означает отрицательный взгляд вперед, $ соответствует концу строки, поэтому (?!$) соответствует символу, которого нет в EOS:

 import pyspark.sql.functions as F
df1.withColumn('zeroRemoved', F.regexp_replace('number', '0 (?!$)', '')).show()
 ------ ----------- 
|number|zeroRemoved|
 ------ ----------- 
|GH0786|      GH786|
|HH7040|      HH740|
|IP0090|       IP90|
| AH567|      AH567|
 ------ ----------- 
  

Ответ №2:

regex_replace Метод предпочтительнее, но вы также могли бы использовать udf для этого:

 from pyspark.sql.functions import col, udf
from pyspark.sql.Types import StringType

def remove_inner_zeroes(my_string):
    if my_string[-1] == '0':
        return my_string.replace('0', '')   '0'
    return my_string.replace('0', '')

remove_inner_zeros_udf = udf(remove_inner_zeros, StringType())
df1.withColumn('zeroRemoved', remove_inner_zeros_udf(col('number')).show()
# ------ ----------- 
#|number|zeroRemoved|
# ------ ----------- 
#|GH0786|      GH786|
#|HH7040|      HH740|
#|IP0090|       IP90|
#| AH567|      AH567|
# ------ ----------- 
  

Или вы могли бы повторить ту же функциональность, используя следующие функции spark:

  • pyspark.sql.Columns.endsWith()
  • pyspark.sql.functions.replace()
  • pyspark.sql.functions.when()
  • pyspark.sql.functions.concat() :

Например:

 from pyspark.sql.functions import col, concat, lit, replace, when

def remove_inner_zeros_spark(string_col):
    return when(
        string_col.endsWith('0'), 
        concat(replace(string_col, '0', ''), lit('0'))
    ).otherwise(replace(string_col, '0', ''))

df1.withColumn('zeroRemoved', remove_inner_zeros_spark(col('number')).show()
# ------ ----------- 
#|number|zeroRemoved|
# ------ ----------- 
#|GH0786|      GH786|
#|HH7040|      HH740|
#|IP0090|       IP90|
#| AH567|      AH567|
# ------ -----------