2015-11-19 79 views
0

信息我使用Windows OS,蟒2.7 我列出所有可用的端口(COM1,3,4),电流输出为:解析和提取字符串

[('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')] 

我的问题是,我想喜欢使用/连接到COM4。所以我希望我能找到一种解析该端口并在之后使用它的方法。即如何从该长串中提取COM4?我计划以PID为目标。

谢谢。

回答

2

一点一点:

>>> ports = [('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')] 

>>> ports[0] 
('COM4', 'Neato Robotics USB Port (COM4)', 'USB VID:PID=2108:780C SNR=XXXX') 

>>> ports[0][2] 
'USB VID:PID=2108:780C SNR=XXXX' 

>>> ports[0][2].split(':') 
['USB VID', 'PID=2108', '780C SNR=XXXX'] 

>>> ports[0][2].split(':')[1] 
'PID=2108' 

>>> ports[0][2].split(':')[1].split('=') 
['PID', '2108'] 

>>> ports[0][2].split(':')[1].split('=')[1] 
'2108' 

>>> int(ports[0][2].split(':')[1].split('=')[1]) 
2108 
+0

它的工作原理,谢谢彼得。我稍微修改它以获得PID 780C。不错的工作! =) –

+0

嗨,彼得,有没有一种方法可以通过PID提取COM端口(COM4)?换句话说,我们先扫描所有PID,然后提取与PID 2018相关的com端口?然后我可以在下一步中使用该COM端口。 –

1

比方说,你的字符串存储在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()