Power BI R 脚本正则表达式仅返回第一个匹配项

Posted

技术标签:

【中文标题】Power BI R 脚本正则表达式仅返回第一个匹配项【英文标题】:Power BI R Script RegEx Only Returns First Match 【发布时间】:2022-01-03 10:09:39 【问题描述】:

我在 Power BI 中有包含 mac 地址的脏数据,并且今天学习了 R,因此我可以使用正则表达式将它们全部提取出来。我可以让一切正常,但它只返回第一个 mac 地址。如果数据包含多个(他们都这样做),则不会返回。

我想将所有 mac 地址作为列表返回到一个新列中,以便在 Power 查询中我可以将它们提取到新行中。

这是我在 Power Query 编辑器中的 Power Query 代码表单。

# 'dataset' holds the input data for this script

# Variables
pattern <- "([0-9A-Fa-f]2[:-])5([0-9A-Fa-f]2)|([0-9a-fA-F]4\\.[0-9a-fA-F]4\\.[0-9a-fA-F]4)"

# Functions
getMacs <- function(x) paste(unlist(regmatches(x, gregexpr(pattern, x))))

# Return
output <- within(dataset,MACs1=getMacs(dataset$NICs))

这是 NIC 列的一行中的示例值。

: -kdnic-[00000000] Microsoft Kernel Debug Network Adapter
11:22:33:44:55:66 : 10.0.0.0; Realtek Gaming 2.5GbE Family Controller
22:33:44:55:66:77 : -Netwtw08-[00000002] Intel(R) Wi-Fi 6 AX200 160MHz
33:44:55:66:77:88 : -vwifimp-[00000003] Microsoft Wi-Fi Direct Virtual Adapter
44:55:66:77:88:99 : -vwifimp-[00000004] Microsoft Wi-Fi Direct Virtual Adapter
 : -BthPan-[00000005] Bluetooth Device (Personal Area Network)
 : -RasSstp-[00000006] WAN Miniport (SSTP)
 : -RasAgile***-[00000007] WAN Miniport (IKEv2)
 : -Rasl2tp-[00000008] WAN Miniport (L2TP)
 : -PptpMiniport-[00000009] WAN Miniport (PPTP)
 : -RasPppoe-[00000010] WAN Miniport (PPPOE)
55:66:77:88:99:00 : -NdisWan-[00000011] WAN Miniport (IP)
66:77:88:99:00:11 : -NdisWan-[00000012] WAN Miniport (IPv6)
77:88:99:00:11:22 : -NdisWan-[00000013] WAN Miniport (Network Monitor)
88:99:00:11:22:22 : -VPPP-[00000014] Virtual PPP Adapter"

返回到我的新 Macs1 列的是每行的 NIC 列中的第一个 mac 地址。我一辈子都想不通如何将所有的mac地址作为一个列表返回。

我已经使用 Visual Studio Code 验证了正则表达式有效,并且 R 代码确实将所有 mac 地址作为字符向量返回。

R Script Variable Contents

做一些研究,我认为我需要将字符向量转换为列表,然后再将其返回给 Power BI。我尝试修改以下行但没有成功。

output <- within(dataset,MACs1=as.list(getMacs(dataset$NICs)))
output <- within(dataset,MACs1=as.data.frame(getMacs(dataset$NICs)))

我知道这将是一些#newbieFail,但我似乎无法弄清楚。感谢任何指示或建议。

干杯

【问题讨论】:

【参考方案1】:

regmatches 返回一个你想要的列表,但是你在你的函数中 unlist() 它。后来你使用as.list()时,哪个字符串在哪个列表项中的信息已经丢失,所以你得到一个大小错误的列表。

解决方法是摆脱您的paste(unlist()) 并使用regmatches 返回的列表:

getMacs <- function(x) regmatches(x, gregexpr(pattern, x))

data = data.frame(string = c(x, x))
data$macs = getMacs(data$string)
data$macs
# [[1]]
# [1] "11:22:33:44:55:66" "22:33:44:55:66:77" "33:44:55:66:77:88" "44:55:66:77:88:99" "55:66:77:88:99:00"
# [6] "66:77:88:99:00:11" "77:88:99:00:11:22" "88:99:00:11:22:22"
# 
# [[2]]
# [1] "11:22:33:44:55:66" "22:33:44:55:66:77" "33:44:55:66:77:88" "44:55:66:77:88:99" "55:66:77:88:99:00"
# [6] "66:77:88:99:00:11" "77:88:99:00:11:22" "88:99:00:11:22:22"

(调用你的字符串x):

x = ": -kdnic-[00000000] Microsoft Kernel Debug Network Adapter
11:22:33:44:55:66 : 10.0.0.0; Realtek Gaming 2.5GbE Family Controller
22:33:44:55:66:77 : -Netwtw08-[00000002] Intel(R) Wi-Fi 6 AX200 160MHz
33:44:55:66:77:88 : -vwifimp-[00000003] Microsoft Wi-Fi Direct Virtual Adapter
44:55:66:77:88:99 : -vwifimp-[00000004] Microsoft Wi-Fi Direct Virtual Adapter
: -BthPan-[00000005] Bluetooth Device (Personal Area Network)
: -RasSstp-[00000006] WAN Miniport (SSTP)
: -RasAgile***-[00000007] WAN Miniport (IKEv2)
: -Rasl2tp-[00000008] WAN Miniport (L2TP)
: -PptpMiniport-[00000009] WAN Miniport (PPTP)
: -RasPppoe-[00000010] WAN Miniport (PPPOE)
55:66:77:88:99:00 : -NdisWan-[00000011] WAN Miniport (IP)
66:77:88:99:00:11 : -NdisWan-[00000012] WAN Miniport (IPv6)
77:88:99:00:11:22 : -NdisWan-[00000013] WAN Miniport (Network Monitor)
88:99:00:11:22:22 : -VPPP-[00000014] Virtual PPP Adapter"

【讨论】:

感谢您澄清数据结构。我像这样删除了 paste(unlist() # Functions getMacs 我不确定如何从 R 函数中执行您的示例中的这些步骤,因为该函数正在数据集的每一行上运行。 data = data.frame(string = c(x, x)) data$macs = getMacs(data$string) data$macs 我的data 是我对您的数据集外观的最佳猜测。如果这不是您的数据的样子,请分享几行数据的示例,而不仅仅是单个条目。 嘿 Gregor 我有一个包含多个列的平面表 computerName、ipAddress、NIC、purchaseDate、age 等。数据源是一个 Excel 电子表格,我使用 Power Query 读取数据。然后我有一个步骤来运行一个 R 脚本,这是我在上面粘贴的脚本。我不清楚如何在函数 getMacs 这是表格的快速屏幕截图link

以上是关于Power BI R 脚本正则表达式仅返回第一个匹配项的主要内容,如果未能解决你的问题,请参考以下文章

Power BI - R 脚本视觉 - Apriori

power BI怎么连接c_r_m

Power BI 中的 Python 脚本将日期返回为 Microsoft.OleDb.Date

python正则表达式如何用已知字符串(如"aaa")替换文件中匹中的分组内容,不是匹中的全部,而是其中一个组

Power BI DAX函数のSUMX函数

关于正则表达式的一些基础知识