【问题标题】:Parsing strings in python在python中解析字符串
【发布时间】:2011-06-20 09:57:58
【问题描述】:

所以我的问题是这样的,我有一个看起来像这样的文件:

[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1

这当然会转化为

' This is an example file!'

我正在寻找一种将原始内容解析为最终内容的方法,以便[BACKSPACE] 将删除最后一个字符(包括空格),多个退格将删除多个字符。 [SHIFT] 对我来说并不重要。感谢大家的帮助!

【问题讨论】:

  • 是 [BACKSPACE] 和 [SHIFT] 唯一需要担心的标记吗?

标签: python string parsing


【解决方案1】:

这是一种方法,但感觉很老套。可能有更好的方法。

def process_backspaces(input, token='[BACKSPACE]'):
    """Delete character before an occurence of "token" in a string."""
    output = ''
    for item in (input+' ').split(token):
        output += item
        output = output[:-1]
    return output

def process_shifts(input, token='[SHIFT]'):
    """Replace characters after an occurence of "token" with their uppecase 
    equivalent. (Doesn't turn "1" into "!" or "2" into "@", however!)."""
    output = ''
    for item in (' '+input).split(token):
        output += item[0].upper() + item[1:]
    return output

test_string = '[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1'
print process_backspaces(process_shifts(test_string))

【讨论】:

    【解决方案2】:

    如果您不关心班次,只需剥离它们,加载

    (defun apply-bspace ()
      (interactive)
      (let ((result (search-forward "[BACKSPACE]")))
        (backward-delete-char 12)
        (when result (apply-bspace))))
    

    并在查看文件时点击M-x apply-bspace。它是 Elisp,而不是 python,但它符合您对“something I can download for free to a PC”的初始要求。

    编辑:如果您也想将 Shift 应用于数字,则 Shift 会比较棘手(因此 [SHIFT]2 => @[SHIFT]3 => # 等)。处理字母的天真方法是

    (defun apply-shift ()
      (interactive)
      (let ((result (search-forward "[SHIFT]")))
        (backward-delete-char 7)
        (upcase-region (point) (+ 1 (point)))
        (when result (apply-shift))))
    

    【讨论】:

    • +1 获得 Elisp 答案!它(我猜这并不太令人惊讶)非常擅长这类事情......我个人是一个 vim 人,但这样的事情有时会把我拉向 emacs。
    • @Joe Kington - 呵呵。老实说,除非有多个需要解析的大文件,否则我会用键盘宏和可能的列表来处理这种事情。只是一个功能更容易分享和解释。
    【解决方案3】:

    这正是你想要的:

    def shift(s):
        LOWER = '`1234567890-=[];\'\,./'
        UPPER = '~!@#$%^&*()_+{}:"|<>?'
    
        if s.isalpha():
            return s.upper()
        else:
            return UPPER[LOWER.index(s)]
    
    def parse(input):
        input = input.split("[BACKSPACE]")
        answer = ''
        i = 0
        while i<len(input):
            s = input[i]
            if not s:
                pass
            elif i+1<len(input) and not input[i+1]:
                s = s[:-1]
            else:
                answer += s
                i += 1
                continue
            answer += s[:-1]
            i += 1
    
        return ''.join(shift(i[0])+i[1:] for i in answer.split("[SHIFT]") if i)
    
    >>> print parse("[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1")
    >>> This is an example file!
    

    【讨论】:

    • 糟糕,我刚刚发现了一个错误……抱歉。现在修复它
    • 调试完成,结果正是你想要的
    【解决方案4】:

    看来您可以使用正则表达式来搜索 (something)[BACKSPACE] 并将其替换为空...

    re.sub('.?\[BACKSPACE\]', '', YourString.replace('[SHIFT]', ''))
    

    不确定您所说的“多个空格删除多个字符”是什么意思。

    【讨论】:

    • -1 这对“blah[BACKSPACE][BACKSPACE][BACKSPACE]arf”有什么作用?
    • 但是它需要在退格之前删除一个空格以及'[BACKSPACE]'它的lef
    • 这就是我的观点——gahooa 的解决方案不适用于我的废话示例。
    • 是的,我刚刚看到你在说什么,到目前为止,我能想到的唯一方法是将 python 与 autoit 或其他手动宏/自动化服务结合起来,但结果会很乏味最好的,但可能不是 100% 正常运行
    【解决方案5】:

    您需要读取输入、提取标记、识别它们并赋予它们含义。

    我会这样做:

    # -*- coding: utf-8 -*-
    
    import re
    
    upper_value = {
        1: '!', 2:'"',
    }
    
    tokenizer = re.compile(r'(\[.*?\]|.)')
    origin = "[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1"
    result = ""
    
    shift = False
    
    for token in tokenizer.findall(origin):
        if not token.startswith("["):
            if(shift):
                shift = False
                try:
                    token = upper_value[int(token)]
                except ValueError:
                    token = token.upper()
    
            result = result + token
        else:
            if(token == "[SHIFT]"):
                shift = True
            elif(token == "[BACKSPACE]"):
                result = result[0:-1]
    

    这不是最快的,也不是优雅的解决方案,但我认为这是一个好的开始。

    希望对你有帮助:-)

    【讨论】:

      猜你喜欢
      • 2013-09-01
      • 2021-01-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 2012-05-16
      • 1970-01-01
      • 2023-04-06
      相关资源
      最近更新 更多