1

CRLF区切り文字で文字列を分割する最良の方法は何ですか?最後に不完全なメッセージがある可能性があります(CRLFなし)?

buf1 = "msg1\r\nmsg2\nmsg3\r\nmsg_no_CRLF"
buf2 = "msg1\r\nmsg2\nmsg3\r\nmsg4\r\n"

a = buf1.scan(/.*\r?\n|.*/)
>>> ["msg1\r\n", "msg2\n", "msg3\r\n", "msg_no_CRLF", ""]

a = buf2.scan(/.*\r?\n|.*/)
>>> ["msg1\r\n", "msg2\n", "msg3\r\n", "msg4\r\n", ""]

配列の最後の項目について、空の文字列または不完全なメッセージを取得しようとしました。

>>> ["msg1\r\n", "msg2\n", "msg3\r\n", "msg_no_CRLF"]
>>> buf1 = a.last #  "" or "msg_no_CRLF"  

編集:私はこの方法を持っています:

def read
  msgs = []
  @buffer << @socket.read_nonblock(1024)
  while @buffer.slice!(/(.*)\r?\n/)
    msgs << $1
  end
  msgs
end

それは機能しますが、スキャンまたは分割を使用して2行で同じことを試みます。

このメソッドは、完全なメッセージ (各 CRLF の前のすべての部分) の配列を返す必要があります。

@buffer = "msg1\r\nmsg2\r\n" 
# Ok, return ["msg1", "msg2"] and @buffer is set to ""

@buffer = "msg1\r\nmsg2"
# incomplete msg2, return ["msg1"] and @buffer is set to "msg2" for the next read.

私の英語で申し訳ありませんが、正しく説明するのは難しいです。

4

2 に答える 2

0

私は次のようなものを使用します:

buf1 = "msg1\r\nmsg2\n\msg3\r\nmsg_no_CRLF"
buf2 = "msg1\r\nmsg2\n\msg3\r\nmsg4\r\n"

buf1.split(/([\r\n]+)/) # => ["msg1", "\r\n", "msg2", "\n", "msg3", "\r\n", "msg_no_CRLF"]
buf2.split(/([\r\n]+)/) # => ["msg1", "\r\n", "msg2", "\n", "msg3", "\r\n", "msg4", "\r\n"]

buf1.split(/([\r\n]+)/).each_slice(2).map(&:join) 
# => ["msg1\r\n", "msg2\n", "msg3\r\n", "msg_no_CRLF"]

buf2.split(/([\r\n]+)/).each_slice(2).map(&:join) 
# => ["msg1\r\n", "msg2\n", "msg3\r\n", "msg4\r\n"]
于 2013-11-11T02:29:39.970 に答える
0

スライスとの別の可能性。

msgs = []
while buf1.slice!(/(.*?)\r?\n/)
  msgs << $1
end

# msgs: ["msg1", "msg2", "msg3"]
# buf1: "msg_no_CRLF"

# msgs: ["msg1", "msg2", "msg3", "msg4"]
# buf2: ""

そのようなことをするためのアイデアはありますか?

msgs = buf1.scan(//)
buf1 = msgs.pop
于 2013-11-11T01:28:19.820 に答える