【问题标题】:Handling escape characters in a string处理字符串中的转义字符
【发布时间】:2016-11-18 17:44:18
【问题描述】:

我需要转换来自用户输入的字符串。用例非常简单:

  • 当字符串中有分号时,字符串被分成多行。
  • 当连续有两个分号时,它们将转换为一个。

理论上问题不大。我使用 Python,但我相信其他使用其他语言的人会发现使用正则表达式很容易。

import re

def get_lines(text):
    """Return a list of lines (list of str)."""
    command_stacking = ";"
    delimiter = re.escape(command_stacking)
    re_del = re.compile("(?<!{s}){s}(?!{s})".format(s=delimiter), re.UNICODE)
    chunks = re_del.split(text)

    # Clean the double delimiters
    for i, chunk in enumerate(chunks):
        chunks[i] = chunk.replace(2 * command_stacking, command_stacking)

    return chunks

这似乎有效:

>>> get_lines("first line;second line;third line with;;a semicolon")
['first line', 'second line', 'third line with;a semicolon']
>>>

但是当有三个或四个分号时,它的行为就不像预期的那样。

正则表达式会忽略多个分号(应该如此),但是当用; 替换;; 时,;;; 会被;; 替换,;;;; 会被;;... 替换等等在。如果将 2 替换为 1、3 替换为 2、4 替换为 3,那就太好了……我可以向我的用户解释这一点。

最好的解决方案是什么?

感谢您的帮助,

【问题讨论】:

    标签: python regex escaping


    【解决方案1】:

    re.sub 的 repl 参数可以是一个函数。

    >>> s = 'a;;b;;;c;;;;d'
    >>> pattern = ';{2,}'
    >>> def f(m):
        return m.group(0)[1:]
    
    >>> re.sub(pattern, f, s)
    'a;b;;c;;;d'
    >>> 
    

    【讨论】:

      【解决方案2】:

      而不是字符串replace 方法使用re.sub()count=1

      import re
      re.sub(';;', ';', 'foo;;;bar', count=1)
      

      https://docs.python.org/2/library/re.html#re.sub

      【讨论】:

      • 看起来是最好的解决方案,即使我不确定它是如何工作的。它似乎将两个分号替换为 1、3 替换为 2、4 替换为 3、5 替换为 4 等等。
      • count=1 参数告诉它只替换双分号的一个实例。
      【解决方案3】:

      您可以使用re.split 进行环视。

      示例

      >>> re.split(r'(?<!;);(?!;)', string)
      ['first line', 'second line', 'third line with;;a semicolon']
      

      正则表达式

      • (?&lt;!;) 消极看后面。检查; 前面是否没有另一个;
        • ; 匹配 ;
      • (?!;) 负面展望。检查; 后面是否没有另一个;

      >>> [x.replace(';;', ';') for x in re.split(r'(?<!;);(?!;)', string)]
      ['first line', 'second line', 'third line with;a semicolon']
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-31
        • 1970-01-01
        • 2013-03-17
        • 1970-01-01
        • 1970-01-01
        • 2011-04-30
        相关资源
        最近更新 更多