{ "info": { "author": "Behzad Dastur", "author_email": "bdastur@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "rex\n====\n[![PyPI Version](https://img.shields.io/pypi/v/rexutil.svg)](https://pypi.python.org/pypi/rexutil)\n\nA simple python module which serves as an abstraction to the python\nregular expression (re) module in some use cases.\n\n+ [Introduction] (https://github.com/bdastur/rex/blob/master/README.md#introduction)\n+ [Getting Started] (https://github.com/bdastur/rex/blob/master/README.md#getting-started)\n+ [Features] (https://github.com/bdastur/rex/blob/master/README.md#features)\n + [LR Value Parsing] (https://github.com/bdastur/rex/blob/master/README.md#lrvalue)\n + [Multiple LR Value Parsing] (https://github.com/bdastur/rex/blob/master/README.md#mlrvalue)\n + [Table formatParsing] (https://github.com/bdastur/rex/blob/master/README.md#tabular)\n + [RE Pattern Abstractions] (https://github.com/bdastur/rex/blob/master/README.md#pabstractions)\n\n\n------\n# Introduction:\n\nThe rex module was born out of necessity. I found myself writing code to parse a lot of command line output for some switches which did not have a good API interface and also in some cases where CLI was the best option to get the data I needed.\n\nIn a lot of cases the output format was very similar where I could generalize and try to come up with a common API that can be used for any such CLI. I could not find anything that would fit the bill, and rex was born.\n\n------\n# Getting Started:\n\n\n## Installing using pip:\n```\n pip install rexutil\n```\n\n## Installing (git clone):\n```\ngit clone https://github.com/bdastur/rex -b master\n```\n\n## Usage:\n```\n import rex\n```\n\n------\n# Features:\nThe module provides the following main abstractions:\n\n## **1. Parsing a LR Value String:**\nConsider the output of a CLI \"show chassis\" below from a switch. \n```\n chassis : UCS43\n Serial no : USC788dc\n Firmware : 12.01(99)\n PID : UCS4343\n UUID : URY888dR7R7R8-090-99\n Description : Ucs M3 Series Chassis\n\n```\nThe LRValue parser will parse this output and return a dictionary:\n```\n{ \n 'firmware': '12.01(99)', \n 'description': 'Ucs M3 Series Chassis', \n 'serial_no': 'USC788dc',\n 'pid': 'UCS4343', \n 'chassis': 'UCS43', \n 'uuid': 'URY888dR7R7R8-090-99'\n }\n```\n\n## **2. Parsing multiple LR Value strings.**\nA similar use case is where you have multiple blocks of LRValue paris.\nConsider the example of a CLI to display adapters.\n```\nPhysical Drive Number 21: \n Controller: SLOT-4 \n Health: Good \n Status: Unconfigured Good \n Manufacturer: ATA \n Model: ST91000640NS \n Predictive Failure Count: 0 \n Drive Firmware: CC03 \n Coerced Size: 952720 MB \n Type: HDD \nPhysical Drive Number 22: \n Controller: SLOT-4 \n Health: Good \n Status: Unconfigured Good \n Manufacturer: ATA \n Model: ST91000640NS \n Predictive Failure Count: 0 \n Drive Firmware: CC03 \n Coerced Size: 952720 MB \n```\n\nIn this case the LRValue parser will parse the output and\nreturn a list of dictionary object\n```\n[ { },\n { 'coerced_size': '952720 MB',\n 'controller': 'SLOT-4',\n 'drive_firmware': 'CC03',\n 'health': 'Good',\n 'manufacturer': 'ATA',\n 'model': 'ST91000640NS',\n 'physical_drive_number': '',\n 'predictive_failure_count': '0',\n 'status': 'Unconfigured Good',\n 'type': 'HDD'},\n { 'coerced_size': '952720 MB',\n 'controller': 'SLOT-4',\n 'drive_firmware': 'CC03',\n 'health': 'Good',\n 'manufacturer': 'ATA',\n 'model': 'ST91000640NS',\n 'physical_drive_number': '',\n 'predictive_failure_count': '0',\n 'status': 'Unconfigured Good'}]\n```\n\n## **3. Parsing a tabular format string.**\nVery common output format is a tabular format with fields seperated by \ndelimiters (spaces, |, etc).\n\nAn example here is the \"df\" command:\n```\nFilesystem 1K-blocks Used Available Use% Mounted on\n/dev/md1 95926932 27688272 63359156 31% /\nudev 132014724 4 132014720 1% /dev\ntmpfs 52809712 448 52809264 1% /run\nnone 5120 0 5120 0% /run/lock\nnone 132024280 0 132024280 0% /run/shm\ncgroup 132024280 0 132024280 0% /sys/fs/cgroup\n/dev/md0 943544 28960 865820 4% /boot\n/dev/md2 806415824 63998212 701447384 9% /var\n```\n\nHere the taubular string parser will parse the output, and return a list\nof dictionary objects as below:\n```\n[ { '1k-blocks': '95926932',\n 'Available': '63359156',\n 'Filesystem': '/dev/md1',\n 'Mounted_on': '/',\n 'usage%': '31%',\n 'used': '27688272'},\n { '1k-blocks': '132014724',\n 'Available': '132014720',\n 'Filesystem': 'udev',\n 'Mounted_on': '/dev',\n 'usage%': '1%',\n 'used': '4'},\n { '1k-blocks': '52809712',\n 'Available': '52809264',\n 'Filesystem': 'tmpfs',\n 'Mounted_on': '/run',\n 'usage%': '1%',\n 'used': '448'},\n { '1k-blocks': '5120',\n 'Available': '5120',\n 'Filesystem': 'none',\n 'Mounted_on': '/run/lock',\n 'usage%': '0%',\n 'used': '0'},\n { '1k-blocks': '132024280',\n 'Available': '132024280',\n 'Filesystem': 'none',\n 'Mounted_on': '/run/shm',\n 'usage%': '0%',\n 'used': '0'},\n { '1k-blocks': '132024280',\n 'Available': '132024280',\n 'Filesystem': 'cgroup',\n 'Mounted_on': '/sys/fs/cgroup',\n 'usage%': '0%',\n 'used': '0'},\n { '1k-blocks': '943544',\n 'Available': '865820',\n 'Filesystem': '/dev/md0',\n 'Mounted_on': '/boot',\n 'usage%': '4%',\n 'used': '28960'},\n { '1k-blocks': '806415824',\n 'Available': '701447384',\n 'Filesystem': '/dev/md2',\n 'Mounted_on': '/var',\n 'usage%': '9%',\n 'used': '63998212'}]\n\n```\n\n\n## **4. Common (re) Pattern Abstractions**\nAnother use case where parsing strings is needed is in logs and other program output. \nSome of the common patterns which can abstract a lot of pain in writing regular expression strings\nare below:\n\n### 1. IP Address:\nHere is an example of a log from haproxy:\n```\nNov 16 16:35:06 testhost1 haproxy[37217]: 192.16.41.8:45133 [16/Nov/2015:16:32:04.152] mysql mysql/mysql1 1/0/182236 12736 -- 647/261/261/261/0 0/0\nNov 16 16:35:06 testhost1 haproxy[37217]: 192.16.41.8:45100 [16/Nov/2015:16:32:03.525] mysql mysql/mysql1 1/0/182932 13077 -- 647/261/261/261/0 0/0\nNov 16 16:35:06 testhost1 haproxy[37217]: 192.16.41.8:45131 [16/Nov/2015:16:32:04.105] mysql mysql/mysql1 1/0/182483 12592 -- 647/261/261/261/0 0/0\nNov 16 16:35:07 testhost1 haproxy[37217]: 192.16.41.8:45182 [16/Nov/2015:16:32:05.396] mysql mysql/mysql1 1/0/182246 8352 -- 647/261/261/261/0 0/0\nNov 16 16:35:07 testhost1 haproxy[37217]: 192.16.41.4:55572 [16/Nov/2015:16:32:07.711] mysql mysql/mysql1 1/0/180119 16915 -- 647/261/261/261/0 0/0\n\n```\n\nConsider we want to parse the log and get all the ip addresses and ports. Here is how we can do that\nusing the rex reformat pattern API.\n\nFirst we define our search pattern:\n```\n# Get the ipaddress and port no from the output. \npattern = \".* (ip:):(d:).*\"\n```\n\nInvoke the rex \"reformat_pattern() API.\n``` \nrexpat = rex.reformat_pattern(pattern) \n```\n\nNow we can use this as a pattern to search. In this case the re.finditer to iterate\nthrough all the matches:\n``` \nfor mobj in re.finditer(rexpat, data): \n print \"IP ADDR: %s, PORT: %s\" % \\ \n (mobj.group(1), mobj.group(2)) \n```\n\nThis returns the output:\n```\nIP ADDR: 192.16.41.8, PORT: 45133\nIP ADDR: 192.16.41.8, PORT: 45100\nIP ADDR: 192.16.41.8, PORT: 45131\nIP ADDR: 192.16.41.8, PORT: 45182\nIP ADDR: 192.16.41.4, PORT: 55572\n```\n\n### 2. MAC Addresses:\n\n### 3. Timestamps:", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/bdastur/rex", "keywords": "re regular expression utility matching development", "license": "Apache Software License", "maintainer": "", "maintainer_email": "", "name": "rexutil", "package_url": "https://pypi.org/project/rexutil/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/rexutil/", "project_urls": { "Homepage": "https://github.com/bdastur/rex" }, "release_url": "https://pypi.org/project/rexutil/1.0.5/", "requires_dist": null, "requires_python": "", "summary": "A python module for regular expression manipulations.", "version": "1.0.5" }, "last_serial": 2073398, "releases": { "1.0.1": [ { "comment_text": "", "digests": { "md5": "08b937a5a659aa4483d896aa3af34794", "sha256": "c374a2e93c2f600c90134a511cd2c0b589718484e522537281471d6486ae7e73" }, "downloads": -1, "filename": "rexutil-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "08b937a5a659aa4483d896aa3af34794", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9732, "upload_time": "2015-11-29T00:22:18", "url": "https://files.pythonhosted.org/packages/e4/c6/57590390ac6c271bed27c5a1df42ae72ed3fa4cacbe58d9c619b38ee7af2/rexutil-1.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d51a2f3315c2d7af5a1718557a30e5c6", "sha256": "f154ce41f08c91d1da5ee885c5c421ef3ab646d67003e7c5984f816d2a0439be" }, "downloads": -1, "filename": "rexutil-1.0.1.tar.gz", "has_sig": false, "md5_digest": "d51a2f3315c2d7af5a1718557a30e5c6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6727, "upload_time": "2015-11-29T00:22:47", "url": "https://files.pythonhosted.org/packages/66/bf/a84e319645fca7ee9040f3009c59072e36357f8f359a2cab10f48cfbac9a/rexutil-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "4cd2fd0aff5e5b38d2e915482493a35d", "sha256": "9b4dee76594a4ee539af038ea627adfe35e6e5b14f4a84f53958551c8a4ba06a" }, "downloads": -1, "filename": "rexutil-1.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4cd2fd0aff5e5b38d2e915482493a35d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10188, "upload_time": "2015-12-09T01:16:38", "url": "https://files.pythonhosted.org/packages/b8/49/f092341cc645e7e940dff6c4665ac2955711456ec0a4f2a1f4361e42015d/rexutil-1.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "46dd869b0538ee47f09fe46a1801ba53", "sha256": "0cffd9d53a15a176ed4fc1960ccdbb5e86c593165fdd34451ac76e0c7a6b1d99" }, "downloads": -1, "filename": "rexutil-1.0.2.tar.gz", "has_sig": false, "md5_digest": "46dd869b0538ee47f09fe46a1801ba53", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6977, "upload_time": "2015-12-09T01:09:29", "url": "https://files.pythonhosted.org/packages/33/7b/986710870ff6a4a8c53c855cad8c32af90c7caeb49d2df241ae9f611823d/rexutil-1.0.2.tar.gz" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "8ffcdb71b2b45f61acd0a262a96cf652", "sha256": "2f779d452fd49008497a08a19c505d4a8fc5a72c757a20c28e0de09e45732cee" }, "downloads": -1, "filename": "rexutil-1.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "8ffcdb71b2b45f61acd0a262a96cf652", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10410, "upload_time": "2015-12-10T21:53:45", "url": "https://files.pythonhosted.org/packages/13/71/b0d558e1f63b2c64eaa8f9c284ddf1e49fcb88114d3092e51a5266121058/rexutil-1.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "968193a4038b66d64fce0d82c1bbbdd5", "sha256": "3f4505041bdf05a93f5a904c5f370e4a95d464c0f4fc949409892ac5138b399f" }, "downloads": -1, "filename": "rexutil-1.0.3.tar.gz", "has_sig": false, "md5_digest": "968193a4038b66d64fce0d82c1bbbdd5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7179, "upload_time": "2015-12-10T21:53:27", "url": "https://files.pythonhosted.org/packages/20/33/cd4383ddf83a63930d40711bf476ea0fe824be3e9c119aaa6c0cd1a02691/rexutil-1.0.3.tar.gz" } ], "1.0.4": [ { "comment_text": "", "digests": { "md5": "38b881f302a441f73da279130e78dbaa", "sha256": "339a384d6bcfd02bd246fbeba7395873725a2e620fbecb14099e6be1a73fc505" }, "downloads": -1, "filename": "rexutil-1.0.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "38b881f302a441f73da279130e78dbaa", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10417, "upload_time": "2015-12-16T10:34:06", "url": "https://files.pythonhosted.org/packages/0b/77/116608358c1983377205756538368b6bf3db638d7023e14bc23806eb01ae/rexutil-1.0.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9f94ce96607ce4e8de2fde848f2175b3", "sha256": "c0d8f9242073e8268dbcdb44be6c9ad83cda5245587f78c6bcec7a3364c34a42" }, "downloads": -1, "filename": "rexutil-1.0.4.tar.gz", "has_sig": false, "md5_digest": "9f94ce96607ce4e8de2fde848f2175b3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7190, "upload_time": "2015-12-16T10:33:55", "url": "https://files.pythonhosted.org/packages/2d/05/901b8d4f3b3f85b4cc0eef846c9bf0aa2bfd10d7b3fb88c5897f8c0285f0/rexutil-1.0.4.tar.gz" } ], "1.0.5": [ { "comment_text": "", "digests": { "md5": "490e285d1efd69dccef5d73faeb25b68", "sha256": "62771af418ecd83c5ca4b4313f20dde3e7d0ecce1200defecd97a7f4c5ca3b74" }, "downloads": -1, "filename": "rexutil-1.0.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "490e285d1efd69dccef5d73faeb25b68", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10617, "upload_time": "2016-04-20T06:29:21", "url": "https://files.pythonhosted.org/packages/6d/d8/de196c8e37659b8b81d2cef9fad7798475f4df489e1303d517653dd6d0ea/rexutil-1.0.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "68bced1eec5b001b9f83ed493b8d2a21", "sha256": "d0fa0626168c3ba0c3017244c782b005dd6c3dc8fc2162fe8e47725f7e873d9e" }, "downloads": -1, "filename": "rexutil-1.0.5.tar.gz", "has_sig": false, "md5_digest": "68bced1eec5b001b9f83ed493b8d2a21", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7324, "upload_time": "2016-04-20T06:28:44", "url": "https://files.pythonhosted.org/packages/5b/99/54fd544670c91570116fa301f8b99af5c17455b0681da4b4632315c0bc1f/rexutil-1.0.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "490e285d1efd69dccef5d73faeb25b68", "sha256": "62771af418ecd83c5ca4b4313f20dde3e7d0ecce1200defecd97a7f4c5ca3b74" }, "downloads": -1, "filename": "rexutil-1.0.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "490e285d1efd69dccef5d73faeb25b68", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10617, "upload_time": "2016-04-20T06:29:21", "url": "https://files.pythonhosted.org/packages/6d/d8/de196c8e37659b8b81d2cef9fad7798475f4df489e1303d517653dd6d0ea/rexutil-1.0.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "68bced1eec5b001b9f83ed493b8d2a21", "sha256": "d0fa0626168c3ba0c3017244c782b005dd6c3dc8fc2162fe8e47725f7e873d9e" }, "downloads": -1, "filename": "rexutil-1.0.5.tar.gz", "has_sig": false, "md5_digest": "68bced1eec5b001b9f83ed493b8d2a21", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7324, "upload_time": "2016-04-20T06:28:44", "url": "https://files.pythonhosted.org/packages/5b/99/54fd544670c91570116fa301f8b99af5c17455b0681da4b4632315c0bc1f/rexutil-1.0.5.tar.gz" } ] }