问题描述
我正在尝试使用正则表达式将字符串拆分为不同的列
下面是我的数据
decodeData = [('M|C705|Exx05','2'),('M|Exx05','4'),('M|C705 P|Exx05','6'),('M|C705 P|8960 L|Exx05','7'),('M|C705 P|78|8960','9')]
df = sc.parallelize(decodeData).toDF(['Decode',''])
dfNew = df.withColumn('Exx05',regexp_extract(col('Decode'),'(M|P|M)(\\|Exx05)',1)).withColumn('C705','(M|P|M)(\\|C705)',1)) .withColumn('8960','(M|P|M)(\\|8960)',1))
dfNew.show()
Result
+--------------------+---+-----+----+-----+
| Decode| |Exx05|C705| 8960|
+--------------------+---+-----+----+-----+
| M|C705|Exx05 | 2 | | M| |
| M|Exx05 | 4 | M| | |
| M|C705 P|Exx05 | 6 | P| M| |
|M|C705 P|8960 L|Exx05| 7 | M| M| P|
| M|C705 P|78|8960 | 9 | | M| |
+--------------------+---+-----+----+-----+
这里我试图提取字符串 Exx05,C705,8960 的代码,这可能属于 M/P/L 代码 例如:在解码 'M|C705 P|8960 L|Exx05' 时,我希望在相应列中的结果为 L M P。但是我在这里遗漏了一些逻辑,我发现很难破解
预期结果
+--------------------+---+-----+----+-----+
| Decode| |Exx05|C705| 8960|
+--------------------+---+-----+----+-----+
| M|C705|Exx05 | | M| M| |
| M|Exx05 | | M| | |
| M|C705 P|Exx05 | | P| M| |
|M|C705 P|8960 L|Exx05| | L| M| P|
| M|C705 P|78|8960 | | | M| P|
+--------------------+---+-----+----+-----+
当我尝试相应地更改 reg 表达式时,它适用于某些情况而不适用于其他示例情况,这只是我正在处理的实际数据的一个子集。
eg: 1. Exx05 可以落入任何代码 M/L/P 甚至可以落入任何位置,开始,中间,结束等
解决方法
您可以在正则表达式中添加 ([^ ])*
以扩展它,使其匹配任何不以空格分隔的连续模式:
dfNew = df.withColumn(
'Exx05',regexp_extract(col('Decode'),'(M|P|L)([^ ])*(\\|Exx05)',1)
).withColumn(
'C705','(M|P|L)([^ ])*(\\|C705)',1)
).withColumn(
'8960','(M|P|L)([^ ])*(\\|8960)',1)
)
dfNew.show(truncate=False)
+---------------------+---+-----+----+----+
|Decode | |Exx05|C705|8960|
+---------------------+---+-----+----+----+
|M|C705|Exx05 |2 |M |M | |
|M|Exx05 |4 |M | | |
|M|C705 P|Exx05 |6 |P |M | |
|M|C705 P|8960 L|Exx05|7 |L |M |P |
|M|C705$P|78|8960 |9 | |M |P |
+---------------------+---+-----+----+----+
,
我们使用 X(?=Y)
也称为 lookahead assertion
怎么样。这确保我们只匹配 X
后跟 Y
from pyspark.sql.functions import*
dfNew = df.withColumn('Exx05','([A-Z](?=\|Exx05))',1)).withColumn('C705','([A-Z](?=\|C705))',1)) .withColumn('8960','([A-Z]+(?=\|[0-9]|8960))',1))
dfNew.show()
+--------------------+---+-----+----+----+
| Decode| t|Exx05|C705|8960|
+--------------------+---+-----+----+----+
| M|C705|Exx05| 2| | M| |
| M|Exx05| 4| M| | |
| M|C705 P|Exx05| 6| P| M| |
|M|C705 P|8960 L|E...| 7| L| M| P|
| M|C705 P|78|8960| 9| | M| P|
+--------------------+---+-----+----+----+