pyspark正则表达式提取全部

发布于 2025-01-12 08:15:37 字数 1099 浏览 2 评论 0原文

我有一个如下所示的数据框。

id  | js                                    |
0   | bla var test bla ..                   |
1   | bla function RAM blob                 |
2   | function CPU blob blob                |
3   | thanks                                |
4   | bla var AWS and function twitter blaa |

我正在尝试提取 function 或 var 之后的下一个单词

我的代码在这里。

pattern3 = "(func)\s+(\w+)|(var)\s+(\w+)"

df = df.withColumn("js_extracted2", f.regexp_extract(f.col("js"),pattern3,4))

由于它仅捕获一个单词,因此最后一行仅返回 AWS 而不是 Twitter。

所以我想捕获所有匹配。

我的spark版本小于3,

所以我尝试了 df.withColumn('output', f.expr("regexp_extract_all(js, '(func)\s+(\w+)|(var)\s+(\w+ )', 4)")).show()

但它只为所有行返回空。

我的预期输出是

id  | js                                    | output
0   | bla var test bla ..                   | [test]
1   | bla function RAM blob                 | [RAM]
2   | function CPU blob blob                | [CPU]
3   | thanks                                | 
4   | bla var AWS and function twitter blaa | [AWS, twitter]

I have a dataframe like below.

id  | js                                    |
0   | bla var test bla ..                   |
1   | bla function RAM blob                 |
2   | function CPU blob blob                |
3   | thanks                                |
4   | bla var AWS and function twitter blaa |

I am trying to extract the next word after function or var

My code is here.

pattern3 = "(func)\s+(\w+)|(var)\s+(\w+)"

df = df.withColumn("js_extracted2", f.regexp_extract(f.col("js"),pattern3,4))

as it is capture only one word, the final row returns only AWS and not Twitter.

So I would like to capture all matching.

My spark version is less than 3,

so I tried df.withColumn('output', f.expr("regexp_extract_all(js, '(func)\s+(\w+)|(var)\s+(\w+)', 4)")).show()

but it returns only empty for all rows.

my expected output is

id  | js                                    | output
0   | bla var test bla ..                   | [test]
1   | bla function RAM blob                 | [RAM]
2   | function CPU blob blob                | [CPU]
3   | thanks                                | 
4   | bla var AWS and function twitter blaa | [AWS, twitter]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叹梦 2025-01-19 08:15:38

在断言 (?<=i)j 背后使用积极的态度。仅当 i 紧邻左侧时才提取 j

df.withColumn('name', regexp_extract('js', '((?<=function|var)(\s\w+))',1)).show()

---+--------------------+-----+
| id|                  js| name|
+---+--------------------+-----+
|  0| bla var test bla ..| test|
|  1| bla function RAM...|  RAM|
|  2|function CPU blob...|  CPU|
|  3|             thanks |     |
|  4|bla var AWS and f...|  AWS|
+---+--------------------+-----+

use a positive look behind ascertion (?<=i)j. That is extract j only if i is immediately to its left

df.withColumn('name', regexp_extract('js', '((?<=function|var)(\s\w+))',1)).show()

---+--------------------+-----+
| id|                  js| name|
+---+--------------------+-----+
|  0| bla var test bla ..| test|
|  1| bla function RAM...|  RAM|
|  2|function CPU blob...|  CPU|
|  3|             thanks |     |
|  4|bla var AWS and f...|  AWS|
+---+--------------------+-----+
听闻余生 2025-01-19 08:15:38

对我来说,这个问题看起来更像是如何在不使用 regexp_extract_all 的情况下做到这一点

这是另一种不使用正则表达式的方法,以防万一使用 regexp_extract_all 时出现问题:

noofwordstoextract = 1
df.withColumn("ArrayOfWords",F.split("js"," "))\
.withColumn("test",F.expr(f"""filter(transform(ArrayOfWords,(x,e)-> 
CASE WHEN x in ('var','function') 
THEN array_join(slice(ArrayOfWords,e+2,{noofwordstoextract}),' ') ELSE NULL END)
,y-> y is not NULL)""")).drop("ArrayOfWords").show()


+---+-------------------------------------+--------------+
|id |js                                   |test          |
+---+-------------------------------------+--------------+
|0  |bla var test bla ..                  |[test]        |
|1  |bla function RAM blob                |[RAM]         |
|2  |function CPU blob blob               |[CPU]         |
|3  |thanks                               |[]            |
|4  |bla var AWS and function twitter blaa|[AWS, twitter]|
+---+-------------------------------------+--------------+

此解决方案将字符串拆分为数组,然后检查当前元素是否在“var”或“function”中,然后提取接下来的 n 个单词(此处为 1),然后将它们连接起来形成原始字符串(尝试使用 noofwordstoextract=2)以了解更多详细信息。

The question looks more like how to do this without using regexp_extract_all to me.

Here is another way without regex, just incase one has a problem of using regexp_extract_all:

noofwordstoextract = 1
df.withColumn("ArrayOfWords",F.split("js"," "))\
.withColumn("test",F.expr(f"""filter(transform(ArrayOfWords,(x,e)-> 
CASE WHEN x in ('var','function') 
THEN array_join(slice(ArrayOfWords,e+2,{noofwordstoextract}),' ') ELSE NULL END)
,y-> y is not NULL)""")).drop("ArrayOfWords").show()


+---+-------------------------------------+--------------+
|id |js                                   |test          |
+---+-------------------------------------+--------------+
|0  |bla var test bla ..                  |[test]        |
|1  |bla function RAM blob                |[RAM]         |
|2  |function CPU blob blob               |[CPU]         |
|3  |thanks                               |[]            |
|4  |bla var AWS and function twitter blaa|[AWS, twitter]|
+---+-------------------------------------+--------------+

This solution splits the strings into an array then checks the current element is in 'var' or 'function' and then extracts the next n words (here 1) and then joins them to form the original string (try with noofwordstoextract=2) for more details.

救星 2025-01-19 08:15:37

需要用四个\组成一个正则表达式。

df = df.withColumn("js_extracted2", F.expr(f"regexp_extract_all(js, '(function|var)\\\\s+(\\\\w+)', 2)"))
df.show(truncate=False)

You need to use four \ to form a regular expression.

df = df.withColumn("js_extracted2", F.expr(f"regexp_extract_all(js, '(function|var)\\\\s+(\\\\w+)', 2)"))
df.show(truncate=False)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文