2015-11-19 80 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()