如何在pyspark中使用regexp_extract_all提取完全相同的单词

0x6upsns  于 2022-12-04  发布在  Apache
关注(0)|答案(2)|浏览(302)

我在查找正确的正则表达式时遇到一些问题
假设我有一个关键词列表:
关键词=['b.o. o','a.b. a','titi']
(请记住,在任何关键字之前都有一个空格,这个列表可以包含多达100个关键字,所以如果没有函数,我就无法找到它)和我 Dataframe df:
enter image description here
我使用下面的代码来提取匹配的单词,它的部分工作,因为它提取甚至不是一个完全匹配的单词:

keywords = [' b.o.o', ' a.b.a', ' titi']

pattern = '(' + '|'.join([fr'\\b({k})\\b' for k in keywords]) + ')'

df.withColumn('words', F.expr(f"regexp_extract_all(colB, '{pattern}' ,1)))

输出:
enter image description here
但以下是预期的输出:
enter image description here正如我们所看到的,它确实提取了不完全匹配的单词,它没有考虑点。例如,这段代码认为awbwa是匹配的,因为如果我们用点替换w,它将是匹配的。

pattern = '(' + '|'.join([fr'\\b({k})\\b' for k in [re.escape(x) for x in keywords]]) + ')'

在每个点之前和空格之前加一个反斜杠,但它不起作用。
非常感谢你的帮助(顺便说一句,我在stackoverflow上到处找,我没有找到这个问题的答案)

jtw3ybtb

jtw3ybtb1#

我认为您需要在正则表达式模式中的点之前添加一个反斜杠来转义它,这样它就被视为一个文本点,而不是一个匹配任何字符的特殊字符。
在代码中,可以尝试使用re模块中的re.escape()方法对关键字列表中的所有特殊字符进行转义,然后再将它们加入到模式中。

import re

keywords = [' b.o.o', ' a.b.a', ' titi']

# Escape special characters in the keywords using re.escape()
escaped_keywords = [re.escape(keyword) for keyword in keywords]

# Join the escaped keywords with '|' as the separator
pattern = '(' + '|'.join(escaped_keywords) + ')'

# Use the pattern in your regexp_extract_all() call
df.withColumn('words', F.expr(f"regexp_extract_all(colB, '{pattern}' ,1)"))

这应该会给予预期的输出,其中只会撷取完全相符的项目。

vngu2lb8

vngu2lb82#

可以使用\b字边界元字符仅匹配整个字,并在正则表达式中使用反斜杠\.对点进行转义。
以下是一个示例:

import pyspark.sql.functions as F

keywords = [' b.o.o', ' a.b.a', ' titi']

# Escape dots and add word boundaries
pattern = '(' + '|'.join([fr'\b({k.replace(".", "\\.")})\b' for k in keywords]) + ')'

df.withColumn('words', F.expr(f"regexp_extract_all(colB, '{pattern}' ,1)))

这将匹配b.o.o、a.b.a和titi作为整个单词,而不匹配诸如awbwa之类的子字符串。

相关问题