比方說,你的字符串存儲在value
變量:
value = "[('COM4', 'Neato Robotics USB Port (COM4)', 'USB VID:PID=2108:780C SNR=XXXX'), ('COM3', 'Intel(R) Active Management Technology - SOL (COM3)', 'PCI\\VEN_8086&DEV_9C3D&SUBSYS_05DE1028&REV_04\\3&11583659&0&B3'), ('COM1', 'Communications Port (COM1)', 'ACPI\\PNP0501\\0')]"
data = [tuple(item[1:][:-1].split("', '")) for item in value[2:][:-2].split('), (')]
考慮:
data = [('COM4', 'Neato Robotics USB Port (COM4)', 'USB VID:PID=2108:780C SNR=XXXX'), ('COM3', 'Intel(R) Active Management Technology - SOL (COM3)', 'PCI\\VEN_8086&DEV_9C3D&SUBSYS_05DE1028&REV_04\\3&11583659&0&B3'), ('COM1', 'Communications Port (COM1)', 'ACPI\\PNP0501\\0')]
然後可以使用正則表達式來提取PID值:
import re
pid = re.search('VID:PID=.*:(.*) ', data[0][2]).group(1)
如果你想同時VID和PID:
import re
match = re.search('VID:PID=(.*):(.*) ', data[0][2])
if match and len(match.groups()) > 0:
vid = match and match.group(1) or None
pid = match and match.group(2) or None
更新
爲了端口映射到PID或副相反:
import re
data = [('COM4', 'Neato Robotics USB Port (COM4)', 'USB VID:PID=2108:780C SNR=XXXX'), ('COM3', 'Intel(R) Active Management Technology - SOL (COM3)', 'PCI\\VEN_8086&DEV_9C3D&SUBSYS_05DE1028&REV_04\\3&11583659&0&B3'), ('COM1', 'Communications Port (COM1)', 'ACPI\\PNP0501\\0')]
def extract_pid(dev_string):
match = re.search('PID=.*:(.*) ', dev_string)
groups = match and match.groups()
return groups and len(groups) > 0 and groups[0] or None
port_to_pid_dict = dict((item[0], extract_pid(item[2])) for item in data)
# port_to_pid_dict = {'COM1': None, 'COM3': None, 'COM4': '2108'}
pid_to_port_dict = dict((extract_pid(item[2]), item[0]) for item in data if 'PID=' in item[2])
# pid_to_port_dict = {'2108': 'COM4'}
然後你可以使用pid_to_port_dict['2018']
,其中給出'COM4'
。
當然,如果你有在同一時間連接到計算機的相同產品的多個實例的附加邏輯將是必要的:
import collections
pid_to_port_dict = collections.defaultdict(list)
for item in data:
pid = extract_pid(item[2])
if pid:
pid_to_port_dict[pid].append(item[0])
現在pid_to_port_dict['2018']
將導致與端口的陣列的產品與特定的productId連接到:['COM4']
。
由於來自不同供應商的多個產品可能具有相同的產品ID,因此檢查產品ID和供應商ID可能會更好。
更新2
這裏是我會怎麼做。點擊here查看互動示例。
import collections
import re
class Device:
def __init__(self, vendorId, productId, port):
self.vendorId = vendorId
self.productId = productId
self.port = port
def __repr__(self):
return self.__str__()
def __str__(self):
return "Device {}:{} at {}".format(self.vendorId, self.productId, self.port)
def create_defaultdict_with_list():
return collections.defaultdict(list)
class DeviceParser:
def __init__(self, devices):
self.devices = devices
@staticmethod
def _parse(device_string, port):
match = re.search('VID:PID=(.*):(.*) ', device_string)
if match and len(match.groups()) == 2:
return Device(vendorId=match.group(1),
productId=match.group(2),
port=port)
return None
def parse_as_list(self):
devices = []
for port, description, dev_str in self.devices:
dev = self._parse(dev_str, port)
if dev:
devices.append(dev)
return devices
def parse_as_vendor_map(self):
vendors = collections.defaultdict(create_defaultdict_with_list)
for port, description, dev_str in self.devices:
dev = self._parse(dev_str, port)
if not dev:
continue
vendors[dev.vendorId][dev.productId].append(dev)
return vendors
def main():
data = [
('COM4', 'Neato Robotics USB Port (COM4)', 'USB VID:PID=2108:780C SNR=XXXX'),
('COM3', 'Intel(R) Active Management Technology - SOL (COM3)', 'PCI\\VEN_8086&DEV_9C3D&SUBSYS_05DE1028&REV_04\\3&11583659&0&B3'),
('COM1', 'Communications Port (COM1)', 'ACPI\\PNP0501\\0')
]
parser = DeviceParser(data)
devices = parser.parse_as_list()
print('recognized device list:', devices)
vendors = parser.parse_as_vendor_map()
print('device by vendorId and productId:', vendors['2108']['780C'])
print('port of device:', vendors['2108']['780C'][0].port)
if __name__ == '__main__':
main()
它的工作原理,謝謝彼得。我稍微修改它以獲得PID 780C。不錯的工作! =) –
嗨,彼得,有沒有一種方法可以通過PID提取COM端口(COM4)?換句話說,我們先掃描所有PID,然後提取與PID 2018相關的com端口?然後我可以在下一步中使用該COM端口。 –