由于您不了解正则表达式,因此我们暂时将它们排除在外,并尝试手动解析,这更容易理解。
您的原始输入,没有外部撇号和变量名称是:
"{\"@Network\":{\"command\":\"Connect\",\"data\":{\"Id\":\"xx:xx:xx:xx:xx:xx\" ,\"姓名\":\"somename\",\"密码\":\"123456789\"}}}\0"
你说你需要得到'somename'值并且'语法不会改变'。凉爽的!。
首先,看看是什么分隔了这个值:它有引号,然后是左边的冒号和右边的逗号。不过,看看其他部分,这样的布局也用在了靠近command
和靠近的地方pwd
。所以,冒号-引用-数据-引用-逗号是不够的。再往两边看,有一个\"Name\"
。除了这个地方,它永远不会出现在输入数据中的任何地方。这太棒了!也就是说,我们只要搜索\"Name\"
文本就可以快速找到数据的去向:
inputdata = .....
estposition = inputdata.index('\"Name\"')
raise "well-known marker wa not found in the input" unless estposition
现在,我们知道:
- 部分开始的地方
- 并且在“名称”文本之后总是有一个冒号,一个引号,然后是-interesting-data
- 并且在有趣的数据之后总是有一个引用
让我们找到所有这些:
colonquote = inputdata.index(':\"', estposition)
datastart = colonquote+3
lastquote = inputdata.index('\"', datastart)
dataend = lastquote-1
index
返回匹配的开始位置,因此它将返回的位置:
和位置\
。由于我们想要获取它们之间的文本,因此我们必须添加/减去一些位置以从开头移过或从结尾:\"
移回。\"
然后,从它们之间获取数据:
value = inputdata[datastart..dataend]
就是这样。
现在,退后一步,再次查看输入数据。你说语法总是一样的。各个位显然由冒号和逗号分隔。让我们尝试直接使用它:
parts = inputdata.split(/[:,]/)
=> ["\"{\\\"@Network\\\"",
"{\\\"command\\\"",
"\\\"Connect\\\"",
"\\\"data\\\"",
"\n{\\\"Id\\\"",
"\\\"xx",
"xx",
"xx",
"xx",
"xx",
"xx\\\"",
"\\\"Name\\\"",
"\\\"somename\\\"",
"\\\"Pwd\\\"",
"\\\"123456789\\\"}}}\\0\""]
请暂时忽略正则表达式。只是假设它说a colon or comma
。现在,parts
您将获得所有通过inputdata
在每个colon or comma
.
如果布局从不改变并且始终保持不变,那么您的interesting-data 将始终位于第 13 位:
almostvalue = parts[12]
=> "\\\"somename\\\""
现在,只需剥离虚假字符。由于语法是恒定的,因此要从两侧剪切 2 个字符:
value = almostvalue[2..-3]
好的,另一种方式。由于正则表达式已经出现,让我们尝试一下。我们知道:
\"Name\"
数据以冒号和斜杠引号为前缀
- 数据由一些没有引号的文本组成(好吧,至少我猜是这样)
- 数据以斜杠引号结尾
正则表达式语法中的部分分别是:
一起:
inputdata =~ /\\"Name\\":\\"([^\"]*)\\"/
value = $1
请注意,我用 包围了有趣的部分()
,因此在成功匹配后,该部分在$1
特殊变量中可用。
还有一种方式:
如果你仔细看语法,它真的很像一组嵌入的哈希:
\"
{ \"@Network\" :
{ \"command\" : \"Connect\",
\"data\" :
{ \"Id\" : \"xx:xx:xx:xx:xx:xx\",
\"Name\" : \"somename\",
\"Pwd\" : \"123456789\"
}
}
}
\0\"
如果我们写一些类似于 Ruby 哈希的东西:
{ "@Network" =>
{ "command" => "Connect",
"data" =>
{ "Id" => "xx:xx:xx:xx:xx:xx",
"Name" => "somename",
"Pwd" => "123456789"
}
}
}
有什么不同?冒号被替换为=>
,并且引号前的斜杠消失了。哦,打开/关闭 \" 也消失了,\0
最后也消失了。让我们玩:
tmp = inputdata[2..-4] # remove opening \" and closing \0\"
tmp.gsub!('\"', '"') # replace every \" with just "
现在,冒号呢。我们不能只用 替换:
,=>
因为它会损坏零件的内部冒号xx:xx:xx:xx:xx:xx
。但是,看:所有其他冒号之前总是有一个引号!
tmp.gsub!('":', '"=>') # replace every quote-colon with quote-arrow
现在我们tmp
是:
{"@Network"=>{"command"=>"Connect","data"=>{"Id"=>"xx:xx:xx:xx:xx:xx","Name"=>"somename" ,"密码"=>"123456789"}}}
稍微格式化一下:
{ "@Network"=>
{ "command"=>"Connect",
"data"=>
{ "Id"=>"xx:xx:xx:xx:xx:xx","Name"=>"somename","Pwd"=>"123456789" }
}
}
所以,它看起来就像一个 Ruby 哈希。让我们尝试“去字符串化”它:
packeddata = eval(tmp)
value = packeddata['@Network']['data']['Name']
完毕。
好吧,这已经增长了一点,而且Jonas显然更快,所以我将 JSON 部分留给他,因为他已经写了它;)数据与 Ruby 哈希非常相似,因为它显然被格式化为 JSON,它是一个哈希 -也喜欢结构。使用正确的格式读取工具通常是最好的主意,但请注意 JSON 库在被要求读取数据时 - 将读取所有数据,然后您可以询问他们“在关键 xx/yy/zz 里面有什么",就像我向您展示的 read-it-as-a-Hash 尝试一样。有时,当您的程序在截止日期前很短时,您无法通读所有内容。然后,使用正则表达式扫描或手动扫描“已知标记”可能(不是必须)更快,因此更可取。但是,仍然不太方便。