Changeset 1907:9b35fd5ebae0 in orange-bioinformatics


Ignore:
Timestamp:
11/12/13 15:22:05 (5 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

Fixed obo tag value parsing.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • orangecontrib/bio/obiOntology.py

    r1873 r1907  
    105105 
    106106    """ 
    107     head, tail = string.split(sep, 1) 
     107    head, tail = _split_esc(string, sep) 
    108108    return head.rstrip(" "), tail.lstrip(" ") 
     109 
     110 
     111def _rsplit_and_strip(string, sep): 
     112    """ 
     113    Right split the `string` by separator `sep` in to two parts and 
     114    strip any whitespace between the inner parts. 
     115 
     116    """ 
     117    head, tail = _rsplit_esc(string, sep) 
     118    return head.rstrip(" "), tail.lstrip(" ") 
     119 
     120 
     121def _find_esc(string, char): 
     122    i = string.find(char) 
     123    while i != -1: 
     124        if (i > 0 and string[i - 1] != "\\") or string[i - 1] != "\\": 
     125            return i 
     126        else: 
     127            i = string.find(char, i + 1) 
     128    return i 
     129 
     130 
     131def _rfind_esc(string, char): 
     132    i = string.rfind(char) 
     133    while i != -1: 
     134        if (i > 0 and string[i - 1] != "\\") or string[i - 1] != "\\": 
     135            return i 
     136        else: 
     137            i = string.rfind(char, 0, i - 1) 
     138    return i 
     139 
     140 
     141def _split_esc(string, sep, _find_esc=_find_esc): 
     142    i = _find_esc(string, sep) 
     143    if i != -1: 
     144        return string[:i], string[i + 1:] 
     145    else: 
     146        return string, "" 
     147 
     148 
     149def _rsplit_esc(string, sep): 
     150    i = _rfind_esc(string, sep) 
     151    if i != -1: 
     152        return string[:i], string[i + 1:] 
     153    else: 
     154        return string, "" 
     155 
     156 
     157def parse_tag_value(tag_value_string): 
     158    """ 
     159    Parse a tag value string and return a four-tuple containing 
     160    a (tag, value, modifiers, comment). If comment or modifiers are 
     161    not present the corresponding entry will be ``None``. 
     162 
     163    >>> parse_tag_value("foo: bar {modifier=frob} ! Comment") 
     164    ('foo', 'bar', 'modifier=frob', 'Comment') 
     165    >>> parse_tag_value("foo: bar") 
     166    ('foo', 'bar', None, None) 
     167    >>> parse_tag_value("foo: bar [baz:0] { fizz=buzz } ! Comment") 
     168    ('foo', 'bar [baz:0]', 'fizz=buzz', 'Comment') 
     169 
     170    """ 
     171    comment = modifiers = None 
     172    # First get rid of the comment if present 
     173    if _rfind_esc(tag_value_string, "!") != -1: 
     174        tag_value_string, comment = _rsplit_and_strip(tag_value_string, "!") 
     175 
     176    # Split on the first unescaped ":" 
     177    tag, value = _split_and_strip(tag_value_string, ":") 
     178 
     179    # Split the value on { to get the modifiers if present 
     180    value = value.rstrip() 
     181    if value.endswith("}") and not value.endswith(r"\}") and \ 
     182            _rfind_esc(value, "{") != -1: 
     183        value, modifiers = _rsplit_and_strip(value, "{") 
     184        # remove closing } and any whitespace 
     185        modifiers = modifiers[: -1].rstrip() 
     186 
     187    return tag, value, modifiers, comment 
    109188 
    110189 
     
    313392        lines = stanza.splitlines() 
    314393        stanza_type = lines[0].strip("[]") 
    315         tag_values = [] 
    316         for line in lines[1:]: 
    317             if ":" in line: 
    318                 tag_values.append(cls.parse_tag_value(line)) 
     394#        tag_values = [] 
     395#        for line in lines[1:]: 
     396#            if ":" in line: 
     397#                tag_values.append(cls.parse_tag_value(line)) 
     398        tag_values = [cls.parse_tag_value(line) for line in lines[1:] 
     399                      if ":" in line] 
    319400 
    320401        obo = OBOObject(stanza_type) 
     
    324405 
    325406    @classmethod 
    326     def parse_tag_value_1(cls, tag_value_pair, *args): 
     407    def parse_tag_value(cls, tag_value_pair, *args): 
    327408        """ 
    328409        Parse and return a four-tuple containing a tag, value, a 
     
    366447    _RE_VALUE = re.compile(r"^\s*(?P<value>.+?)\s*(?P<modifiers>[^\\]{.+?[^\\]})?\s*(?P<comment>[^\\]!.*)?$") 
    367448 
     449    _RE_TAG_VALUE = re.compile( 
     450        r"^(?P<tag>.+?)\s*(?<!\\):\s*(?P<value>.+?)\s*(?P<modifiers>(?<!//){.*?(?<!//)})?\s*(?P<coment>(?<!//)!.*)?$") 
     451    _RE_VALUE = re.compile( 
     452        r"^\s*(?P<value>.+?)\s*(?P<modifiers>(?<!//){.*?(?<!//)})?\s*(?P<coment>(?<!//)!.*)?$") 
     453 
    368454    @classmethod 
    369     def parse_tag_value(cls, tag_value_pair, arg=None): 
     455    def parse_tag_value_1(cls, tag_value_pair, arg=None): 
    370456        """ 
    371457        Parse and return a four-tuple containing a tag, value, a list 
     
    491577        startswith = str.startswith 
    492578        endswith = str.endswith 
    493         parse_tag_value = OBOObject.parse_tag_value 
     579#        parse_tag_value = OBOObject.parse_tag_value 
     580        parse_tag_value_ = parse_tag_value 
    494581 
    495582        for line in body.splitlines(): 
     
    500587                yield "COMMENT", line[1:] 
    501588            elif line: 
    502                 yield "TAG_VALUE", parse_tag_value(line) 
     589                yield "TAG_VALUE", parse_tag_value_(line) 
    503590            else:  # empty line is the end of a term 
    504591                yield "CLOSE_STANZA", None 
Note: See TracChangeset for help on using the changeset viewer.