如何用PQ提取不规则文本中的数字?

如何用PQ提取不规则文本中的数字

提问人: 拉登Dony

下面的A列记录了项目的名称,如何把里面的用电量数字,提取到B列?

这是来自Excelhome中的一个提问。看得出作者的Excel水平是很不错的,他尝试了一些办法,但是没有办法得到完美的结果。

1- Ctrl+E,后续还要手动调整

2- 正则表达式,现在正在研究中

回答人: 拉登老师

针对复杂文本的处理,如果要精准的获取,主要有两种方法:

1- 正则表达式,可以应对各种复杂场景,缺点是匹配速度慢

2- M函数,把文本转成list处理,步骤稍微复杂一些,效率上要比正则表达式快一些。

1- M函数实现方法

参考【渡渡orz】大佬的方法,通过添加自定义列可以实现。

具体参考原帖:

如何提取一段文本中的数值 并根据单位及时换算-Power BI-ExcelHome技术论坛 –

2- 代码逻辑梳理

上面的代码,具备了编程高手的几个特征:

1- 代码越写越长。

2- 没有注释。

我梳理了一下代码的逻辑,添加了注释,方便学习理解。

let
    源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
    更改的类型 = Table.TransformColumnTypes(源,{{"项目名称", type text}}),
    已添加自定义 = Table.AddColumn(更改的类型, "自定义", each 
        let
            // 删除所有的数字,作为下一步的拆分分隔符
            text_remove_number = Text.Remove([项目名称],{"0".."9","."}),
            // 根据text_remove_number拆分原始文本,这样可以保留数字,   并得到一个list
            list_keep_number = Text.SplitAny([项目名称],text_remove_number),
            // 清除list中的空白元素
            list_without_empty = List.RemoveItems(list_keep_number,{""}),
            // 提取最后一个数字,作为要返回的结果
            last_number =Number.From(List.Last(list_without_empty)),
            // 判断数值记录的是不是千瓦
            check_kw = List.Contains({"KW","千瓦"},[项目名称],(x,y)=>Text.Contains(Text.Upper(y),x)),
            // 如果是千瓦就直接返回,否则就是兆瓦,*1000后再返回
            result = if check_kw then last_number else last_number*1000
        in
            result
    )
in
    已添加自定义

PQ提取数字的逻辑思路是什么?

代码中有几个不错的思路,值得总结提炼出来,后续处理复杂文本提取,可以复用起来。

1- 用Text.Select()提取数字

提取数字,使用Text.Select()函数也是可以实现的,不过返回的是字符串的结果,如果有多个数字的话,不方便后续的处理。

Text.Select([项目名称],{"0".."9"})

如下图所示

2- 提取数字到清单

案例中的方法非常好,可以把数字拆分成list清单的格式,后续统计个数、提取指定位置的数字,都非常方便。

实现的方法大致分为下面几个步骤:

1- 提取非数字的字符,作为拆分的分隔符。

2- 以非数字拆分文本,得到list清单。

3- list删除掉空白的元素,得到干净的数字清单。

对应的代码如下:

            // 删除所有的数字,作为下一步的拆分分隔符
            text_remove_number = Text.Remove([项目名称],{"0".."9","."}),
            // 根据text_remove_number拆分原始文本,这样可以保留数字
            list_keep_number = Text.SplitAny([项目名称],text_remove_number),
            // 清除list中的空白元素
            list_without_empty = List.RemoveItems(list_keep_number,{""}),
            // 提取最后一个数字,作为要返回的结果

案例文件下载

请点击下面链接,到Excelhome中的帖子,下载案例文件。

https://club.excelhome.net/thread-1647752-1-1.html

联系作者

公众号:拉小登 | 微博:拉登Dony | B站:拉小登Excel

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注