pyspark 即使在正则表达式匹配中找不到一个字符,也拒绝值

s3fp2yjn  于 2023-04-29  发布在  Spark
关注(0)|答案(3)|浏览(142)

我有一个包含允许字符i的值列表。e.-

ALLOWED_CHARS = """[âäàáãåçñéêëèíîïìߣ¬ÂÄÀÁÃÅÇѦøÉÊËÈÍÎÏÌØ«»ðýþ±°ªºæ¸Æ€µ¯¡¿ÐÝÞ®¢¥·©§¶¼½¾^¨×ôöòóõ¹ûüùúÿ²ÔÖÒÓÕ³ÛÜÙÚ]"""

上面的列表值和ASCII值是允许的,如果除此之外的任何其他值都应该给予错误。
对于ASCII和其他字符的组合(例如:任何中文/日文)它给我一个错误,而从ALLOWED_CHARS列表和其他字符(例如:任何中文/日文)它不会给我一个错误。
例如:

input:
+-----------+
|middle_name|
+-----------+
|  ELIZABET@|
|     ROBERT|
| ELIZABET弟|
|  ELIZABETH|
|  ELIZABETH|
| ELI弟ABEßH|
+-----------+
Current Output:
+-----------+
|middle_name|
+-----------+
|           |
|           |
| ELIZABET弟|
|           |
|           |
|           |
+-----------+
Expected Output:
+-----------+
|middle_name|
+-----------+
|           |
|           |
| ELIZABET弟|
|           |
|           |
|ELI弟ABEßH |
+-----------+

ELIZABET弟 contains 弟(Chinese letter) and ascii values and it gives an error, which is correct. ELI弟ABEßH contains 弟(Chinese letter) and ß(present in ALLOWED_CHARS ) should give an error but it doesn't.
你能帮我一下吗。
我正在检查多列的上述条件

isAsciiUdf = udf(lambda z: z.isascii())
 for i in colList:
   df = df.withColumn(i, when(isAsciiUdf(col(i)) == "false", col(i)).otherwise(""))
   df = df.withColumn(i, when(~(col(i).rlike(ALLOWED_CHARS)), col(i)).otherwise(lit("")))

在这里,我首先检查列值是否为非ascii,然后获取列值。然后,我检查ALLOWED_CHARS中是否不存在列值,然后获取这些列值。

eanckbw9

eanckbw91#

试试这个:

ALLOWED_CHARS = """âäàáãåçñéêëèíîïìߣ¬ÂÄÀÁÃÅÇѦøÉÊËÈÍÎÏÌØ«»ðýþ±°ªºæ¸Æ€µ¯¡¿ÐÝÞ®¢¥·©§¶¼½¾^¨×ôöòóõ¹ûüùúÿ²ÔÖÒÓÕ³ÛÜÙÚ"""

df = spark.createDataFrame([
    ('ELIZABET@',),
    ('ROBERT',),
    ('ELIZABET弟',),
    ('ELIZABETH',),
    ('EßLIZABETH',),
    ('EßLI弟ABEßH',),
    ('弟',)
], ['middle_name'])

df = (
    df
    .withColumn('bad_characters', f.regexp_extract(f.col('middle_name'), f'([^\x00-\x7F{ALLOWED_CHARS}])', 1))
    .where(f.length(f.col('bad_characters')) > 0)
)

df.show()

输出为:

+-----------+--------------+                                                    
|middle_name|bad_characters|
+-----------+--------------+
| ELIZABET弟|            弟|
|EßLI弟ABEßH|            弟|
|         弟|            弟|
+-----------+--------------+

正则表达式模式的解释:

  1. ^:表示“不”。
  2. \x00-\x7F:表示ASCII字符
  3. {ALLOWED_CHARS}:添加f-string格式中允许的非ASCII字符。
shyt4zoc

shyt4zoc2#

只需将ALLOWED_CHARS更改为

ALLOWED_CHARS = "^[0-9a-zA-Z_\-@âäàáãåçñéêëèíîïìߣ¬ÂÄÀÁÃÅÇѦøÉÊËÈÍÎÏÌØ«»ðýþ±°ªºæ¸Æ€µ¯¡¿ÐÝÞ®¢¥·©§¶¼½¾^¨×ôöòóõ¹ûüùúÿ²ÔÖÒÓÕ³ÛÜÙÚ]+$"

你的代码工作!!!把你想要的任何字符放在括号之间!!!!我还在ALLOWED_CHAR中添加了ASCII字符。例如:

names = df.schema.names
    for name in names:
        df = df.withColumn(name, when(~(col(name).rlike(ALLOWED_CHARS)), col(name)).otherwise(""))

另外,如果你不想保留行,你可以简单地用途:

names = df.schema.names
        for name in names:
            df = df.filter(~col(name).rlike(ALLOWED_CHARS))
bbmckpt7

bbmckpt73#

对于特定的过滤,rlike()似乎是一个更合乎逻辑的选择。

>>> 
>>> df = spark.createDataFrame(
...     [
...         ('ELIZABET@',),
...         ('ROBERT',),
...         ('ELIZABET弟',),
...         ('ELIZABETH',),
...         ('ELIZABETH',),
...         ('ELI弟ABEßH',),
...     ],
...     schema=['middle_name']
... )

>>> 
>>> df.show()
+-----------+
|middle_name|
+-----------+
|  ELIZABET@|
|     ROBERT|
| ELIZABET弟|
|  ELIZABETH|
|  ELIZABETH|
| ELI弟ABEßH|
+-----------+

>>> GOOD_CHARS='âäàáãåçñéêëèíîïìߣ¬ÂÄÀÁÃÅÇѦøÉÊËÈÍÎÏÌØ«»ðýþ±°ªºæ¸Æ€µ¯¡¿ÐÝÞ®¢¥·©§¶¼½¾^¨×ôöòóõ¹ûüùúÿ²ÔÖÒÓÕ³ÛÜÙÚ'
>>> df.filter(df.middle_name.rlike(f'[^\x00-\x7F{GOOD_CHARS}]')).show()
+-----------+
|middle_name|
+-----------+
| ELIZABET弟|
| ELI弟ABEßH|
+-----------+

>>>

相关问题