2

I have a string:

  ONT ONT     ONT       Auto-neg Speed  Duplex Port   Flow    Native Priority

And i need to get Auto-neg from it (for example). I have start index of this word, for example 24. I need to get space count between previous word ONT and Auto-neg


full code:

    def _find_all(string: str, finding: str) -> list[int]:
        result = []
        for i, _ in enumerate(string):
            if string[i:i + len(finding)] == finding:
                result.append(i)
        return result

    fields = {}
    tables = []
    is_table = False
    is_table_heading = False
    table_heading_raw = ''
    is_notes = False
    table_fields = []

    raw = raw.replace(PAGINATION, '').replace('\x1b[37D', '').replace('x1b[37D', '') # remove stupid pagination
    for line in raw.splitlines():
        if '#' in line: # prompt lines
            continue

        if fullmatch(r'\s*\-{5,}\s*', line.strip()): # divider line
            is_notes = False
            if is_table_heading:
                is_table_heading = False
                continue
            if is_table and not is_table_heading:
                is_table = False
            continue

        if is_table and not is_table_heading: # table field line
            assert tables
            print(table_fields)
            print(split(r'\s+', line))
            # tables[-1].append({key: _parse_value(value) for key, value in zip(table_fields, split(r'\s+', line))})
            continue

        if not is_table and len(split(r'\s+', line)) > 1: # table start heading line
            is_table = True
            is_table_heading = True
            table_heading_raw = line
            table_fields = [c for c in split(r'\s+', line.strip()) if c]
            tables.append([])
            continue

        if is_table_heading: # table next heading line
            spaces = 0
            for i, field in enumerate(table_fields):
                print(len(field) + spaces + len(table_heading_raw) - len(table_heading_raw.lstrip()), len(line) - len(line.lstrip()))
                if len(field) + spaces + len(table_heading_raw) - len(table_heading_raw.lstrip()) == len(line) - len(line.lstrip()):
                    table_fields[i] += '-' + split(r'\s+', line.lstrip(), maxsplit=1)[0]
                    spaces += len((match(r'^\s*\S*', line) or [])[0])
                    line = split(r'^\s*\S*', line)[-1]
                else:
                    raw_index = _find_all(table_heading_raw, field)[table_fields[:i].count(field)]
                    # print(table_heading_raw[raw_index])
                    spaces += len(split(r'\S*', table_heading_raw[_find_all(table_heading_raw, field)[table_fields[:i].count(field)]])[0])

I am trying to make table parser like

  ----------------------------------------------------------------------------
  ONT ONT     ONT       Auto-neg Speed  Duplex Port   Flow    Native Priority
      port    port-type          (Mbps)        switch control VLAN
  ----------------------------------------------------------------------------
  1   2       ETH       enable   auto   auto   on     off     2      0
  ----------------------------------------------------------------------------

I have no clue how to parse table title (it can be multiline).

2
  • 1
    you could get substring text[:24], remove spaces on its right end rstrip() and get length of both strings and substract them. Commented Oct 5 at 18:40
  • other idea: use for-loop from 24 to 0 (to iterate from the end to the beginning) and check char-by-char until you get char different than space. Commented Oct 5 at 18:44

2 Answers 2

3

One idea is to get substring before Auto-neg - it will be text[:24] - and it will have spaces at its end, so using .rstrip() you can remove spaces and later get length of both strings and substract them.

text = "  ONT ONT     ONT       Auto-neg Speed  Duplex Port   Flow    Native Priority"
# test "edge case" with only spaces
# text = "       Auto-neg Speed  Duplex Port   Flow    Native Priority"  

pos = text.find("Auto-neg")

before = text[:pos]   # its length should be `pos`
before_without_spaces = before.rstrip()

#count_spaces = len(before) - len(before_without_spaces)
count_spaces = pos - len(before_without_spaces)

print(count_spaces)  # 7

Other idea is to use for-loop with range(24-1, -1,-1) to iterate from the end of substring to its beginning, and check char-by-char until you get char which is not space.

Because there can be only spaces (and if will be never executed) so it needs to set default value for pos_before and it has to be -1, not 0

text = "  ONT ONT     ONT       Auto-neg Speed  Duplex Port   Flow    Native Priority"
# test "edge case" with only spaces
# text = "       Auto-neg Speed  Duplex Port   Flow    Native Priority"  

pos = text.find("Auto-neg")

pos_before = -1  # default value for "edge case" when there are only spaces (it can't be 0)

for index in range(pos - 1, -1, -1):
    if text[index] != " ":
        pos_before = index
        break

#count_spaces = pos - pos_before - 1
count_spaces = (pos-1) - pos_before  # loop started at `pos-1`

print(count_spaces)  # 7

This doesn't need extra space for text[:24]


Instead of variable pos_before can be used index but it may need to use special construction for/else to set correct value index = -1 (when there are only spaces before Auto-neg and break wasn't executed.)

text = "  ONT ONT     ONT       Auto-neg Speed  Duplex Port   Flow    Native Priority"
# test "edge case" with only spaces
# text = "       Auto-neg Speed  Duplex Port   Flow    Native Priority"  

pos = text.find("Auto-neg")

for index in range(pos - 1, -1, -1):
    if text[index] != " ":
        break
else:  # it is `for/else`, not `if/else` - it is executed when `break` wasn't used
    index = -1  # correct value for "edge case" when there are only spaces

count_spaces = (pos - 1) - index  # loop started at `pos-1`

print(count_spaces)  # 7
Sign up to request clarification or add additional context in comments.

Comments

2

you could get substring text[:24], remove spaces on its right end rstrip() and get length of both strings and substract them.

spaces += len(table_heading_raw[:raw_index]) - len(table_heading_raw[:raw_index].rstrip()) - 1

from furas answer

2 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
this len(table_heading_raw[:raw_index]) should gives value raw_index - if only table_heading_raw is not shorter than raw_index

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.