如何用PQ提取不规则文本中的数字?
如何用PQ提取不规则文本中的数字
提问人: 拉登Dony
下面的A列记录了项目的名称,如何把里面的用电量数字,提取到B列?
这是来自Excelhome中的一个提问。看得出作者的Excel水平是很不错的,他尝试了一些办法,但是没有办法得到完美的结果。
1- Ctrl+E,后续还要手动调整
2- 正则表达式,现在正在研究中
回答人: 拉登老师
针对复杂文本的处理,如果要精准的获取,主要有两种方法:
1- 正则表达式,可以应对各种复杂场景,缺点是匹配速度慢
2- M函数,把文本转成list处理,步骤稍微复杂一些,效率上要比正则表达式快一些。
1- M函数实现方法
参考【渡渡orz】大佬的方法,通过添加自定义列可以实现。
具体参考原帖:
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中的帖子,下载案例文件。
联系作者