python - 如何用正则表达式匹配一定长度的字符串

标签 python regex

对于我的一个项目,我正在尝试实现 BitTorrent 协议(protocol)的一小部分,可以找到 here .具体来说,我想使用它的“Bencoding”部分,这是一种安全编码数据以通过套接字传输的方法。格式如下:

8:a string => "a string"
i1234e => 1234
l1:a1:be => ['a', 'b']
d1:a1:b3:one3:twoe => {'a':'b', 'one':two}

编码部分很容易,但是解码就变得很麻烦了。例如,如果我有一个字符串列表,我无法将它们分成单独的字符串。我尝试了几种不同的解决方案,包括 PyParsing和自定义 token 解析器。我目前正在尝试使用正则表达式,它似乎进展顺利,但我仍然挂断了字符串问题。我当前的正则表达式是:

(?P<length>\d+):(?P<contents>.{\1})

但是,我似乎无法使用第一组作为第二组的长度。有什么好办法吗?还是我的做法完全错误,而答案就在我面前?

最佳答案

您为此使用的任何解析器都需要是有状态的(即记住东西),而正则表达式大体上不是有状态的。他们是这项工作的错误工具。

如果这些是您唯一需要担心的数据类型,我想我只需为每种数据类型编写自定义解析器,在读取第一个字符后将控制权传递给适当的解析器。

我现在实际上会实现一个,但已经晚了。

好吧,我决定写一个实现:

from StringIO import StringIO
import string

inputs = ["10:a stringly",
         "i1234e" ,
         "l1:a1:be",
         "d1:a1:b3:one3:twoe"]

# Constants
DICT_TYPE = 'd'
LIST_TYPE = 'l'
INT_TYPE  = 'i'
TOKEN_EOF = ''
TOKEN_END = 'e'
COLON     = ':'


class BadTypeIndicatorException(Exception):pass


def read_int(stream):

   s = ""

   while True:
      ch = stream.read(1)
      if ch not in [TOKEN_EOF, TOKEN_END, COLON]:
         s += ch
      else:
         break

   return s


def tokenize(stream):

   s = ""

   while True:

      ch = stream.read(1)

      if ch == TOKEN_END or ch == TOKEN_EOF:
         return 

      if ch == COLON:
         length = int(s)
         yield stream.read(length)
         s = ""

      else:
         s += ch


def parse(stream):

   TYPE = stream.read(1)

   if TYPE in string.digits:
      length = int( TYPE + read_int(stream) )
      return stream.read(length)

   elif TYPE is INT_TYPE: 
      return int( read_int(stream) )

   elif TYPE is LIST_TYPE: 
      return list(tokenize(stream))

   elif TYPE is DICT_TYPE:
      tokens = list(tokenize(stream))
      return dict(zip(tokens[0::2], tokens[1::2]))

   else: 
      raise BadTypeIndicatorException



for input in inputs:
   stream = StringIO(input)
   print parse(stream)

关于python - 如何用正则表达式匹配一定长度的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/938065/

相关文章:

python - Pandas 面板

python - 将组聚合为行向量(而不是标量)

python - 应该定义密集层输入的最后一个维度。没有发现。收到完整的输入形状 : <unknown>

javascript - 如何在 Atom 中禁用正则表达式

ruby-on-rails - 如何使用正则表达式从第一段和最后一段中删除所有 <br>

python - 如何在 IOS Swift 应用程序中运行 python 程序

python - 在调试器中运行时中断下一个输出

regex - 大文件中带有反向引用的多行搜索

regex - bash/regex 用于使用复杂模式重建部分不一致的文件

javascript - 匹配多行模式