Я думаю, что вы можете достичь этого с помощью следующего регулярного выражения: (?<=.{2})\w+(?=.{2}@)
(?<=.{2})
: положительный взгляд назад для 2 символов \w+
: любое словосимволы (?=.{2}@)
: положительный прогноз для 2 символов, за которым следует литерал @
Первое использование regexp_extract
для извлечения этого шаблона из вашей строки,
from pyspark.sql.functions import regexp_extract, regexp_replace
df = df.withColumn(
"pattern",
regexp_extract("email", r"(?<=.{2})\w+(?=.{2}@)", 0)
)
df.show()
#+-------------------+-------+
#| email|pattern|
#+-------------------+-------+
#| abc123@gmail.com| c1|
#|123abc123@yahoo.com| 3abc1|
#| abcd@test.com| |
#+-------------------+-------+
Затем используйте regexp_replace
, чтобы создать замену *
такой же длины.
df = df.withColumn(
"replacement",
regexp_replace("pattern", r"\w", "*")
)
df.show()
#+-------------------+-------+-----------+
#| email|pattern|replacement|
#+-------------------+-------+-----------+
#| abc123@gmail.com| c1| **|
#|123abc123@yahoo.com| 3abc1| *****|
#| abcd@test.com| | |
#+-------------------+-------+-----------+
Затем снова используйте regexp_replace
в исходном столбце email
, используя производные столбцы pattern
и replacement
.
Чтобы быть в безопасности, concat
смотрят назад / смотрят в сторону от исходного шаблона при выполнении замены. Для этого нам нужно будет использовать expr
, чтобы передать значения столбца в качестве параметров .
from pyspark.sql.functions import concat, expr, lit
df = df.withColumn(
"mod_email_col",
expr("regexp_replace(email, concat('(?<=.{2})', pattern, '(?=.{2}@)'), replacement)")
)
df.show()
#+-------------------+-------+-----------+-------------------+
#| email|pattern|replacement| mod_email_col|
#+-------------------+-------+-----------+-------------------+
#| abc123@gmail.com| c1| **| ab**23@gmail.com|
#|123abc123@yahoo.com| 3abc1| *****|12*****23@yahoo.com|
#| abcd@test.com| | | abcd@test.com|
#+-------------------+-------+-----------+-------------------+
Наконец, отбросьте промежуточные столбцы:
df = df.drop("pattern", "replacement")
df.show()
#+-------------------+-------------------+
#| email| mod_email_col|
#+-------------------+-------------------+
#| abc123@gmail.com| ab**23@gmail.com|
#|123abc123@yahoo.com|12*****23@yahoo.com|
#| abcd@test.com| abcd@test.com|
#+-------------------+-------------------+
Примечание : я добавил один тестовый пример, чтобы показать, что это ничего не делает, если часть адреса электронной почты состоит из 4 символов или менее.
Обновление . Вот несколько способов обработки крайних случаев, когда часть адреса электронной почты содержит менее 4 символов.
Используемые правила:
- Длина адреса электронной почты составляетбольше 5: сделать выше
- Длина адреса электронной почты составляет 3, 4 или 5: оставить первый и последний символы, маскируя остальные с помощью
*
- Адрес электронной почты имеет длину 1 или2: маска одиночного символа перед
@
Код:
patA = "regexp_replace(email, concat('(?<=.{2})', pattern, '(?=.{2}@)'), replacement)"
patB = "regexp_replace(email, concat('(?<=.{1})', pattern, '(?=.{1}@)'), replacement)"
from pyspark.sql.functions import regexp_extract, regexp_replace
from pyspark.sql.functions import concat, expr, length, lit, split, when
df.withColumn("address_part", split("email", "@").getItem(0))\
.withColumn(
"pattern",
when(
length("address_part") > 5,
regexp_extract("email", r"(?<=.{2})\w+(?=.{2}@)", 0)
).otherwise(
regexp_extract("email", r"(?<=.{1})\w+(?=.{1}@)", 0)
)
).withColumn(
"replacement", regexp_replace("pattern", r"\w", "*")
).withColumn(
"mod_email_col",
when(
length("address_part") > 5, expr(patA)
).when(
length("address_part") > 3, expr(patB)
).otherwise(regexp_replace('email', '\w(?=@)', '*'))
).drop("pattern", "replacement", "address_part").show()
#+-------------------+-------------------+
#| email| mod_email_col|
#+-------------------+-------------------+
#| abc123@gmail.com| ab**23@gmail.com|
#|123abc123@yahoo.com|12*****23@yahoo.com|
#| abcde@test.com| a***e@test.com|
#| abcd@test.com| a**d@test.com|
#| ab@test.com| a*@test.com|
#| a@test.com| *@test.com|
#+-------------------+-------------------+