我的字符串如下:
str1='"{\"@Network\":{\"command\":\"Connect\",\"data\":
{\"Id\":\"xx:xx:xx:xx:xx:xx\",\"Name\":\"somename\",\"Pwd\":\"123456789\"}}}\0"'
我想从上面的字符串中提取 somename 字符串。 xx:xx:xx:xx:xx:xx , somename 和 123456789 的值可以更改,但语法将保持与上述相同。< / p>
我在这个网站上看过类似的帖子,但在上面的例子中不知道如何使用正则表达式。 任何想法如何提取上面的字符串。
答案 0 :(得分:5)
将字符串解析为JSON并以此方式获取值。
require 'json'
str = "{\"@Network\":{\"command\":\"Connect\",\"data\":{\"Id\":\"xx:xx:xx:xx:xx:xx\",\"Name\":\"somename\",\"Pwd\":\"123456789\"}}}\0"
json = JSON.parse(str.strip)
name = json["@Network"]["data"]["Name"]
pwd = json["@Network"]["data"]["Pwd"]
答案 1 :(得分:1)
由于你不知道正则表达式,让我们暂时不做它们并尝试手动解析,这更容易理解。
您的原始输入,没有外部撇号和变量名称是:
“{\” @网络\ “:{\” 命令\ “:\” 连接\ “\ ”数据\“:{\ ”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
现在,我们知道:
让我们找到所有这些:
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
切成碎片而检测到的所有部分。
如果布局永远不会改变并且始终相同,那么您感兴趣的数据将始终位于第13位:
almostvalue = parts[12]
=> "\\\"somename\\\""
现在,只是删除虚假角色。由于语法是不变的,所以从两边都要切出两个字符:
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
部分的内部冒号..但是,看看:所有< strong>其他冒号总是在他们面前引用!
tmp.gsub!('":', '"=>') # replace every quote-colon with quote-arrow
现在我们的tmp
是:
{ “@网络”=&GT; { “命令”=&gt; “中连接”, “数据”=&GT; { “ID”=&gt; “中XX:XX:XX:XX:XX:XX”,”名称 “=&gt;” 中somename”, “密码”=&gt; “中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 hash非常相似,因为它显然格式化为JSON,这也是类似哈希的结构。使用正确的格式阅读工具通常是最好的想法,但请注意,当被要求阅读数据时,JSON库将读取所有数据,然后您可以询问它们“内部有什么内容”关键的xx / yy / zz“,就像我向你展示了一下这样的哈希尝试。有时当你的课程在截止日期前很短时,你就无法全部阅读。然后,使用正则表达式扫描或手动扫描“已知标记”可能(不一定)要快得多,因此更加优先。但是,更不方便。玩得开心。