这个正则要怎么写呢?一个不标准的 json 字符串,想要手动给他修改正确

2022-07-24 12:49:12 +08:00
 morri

已经完成了键的修改,没把加""的都加上了, 但值要如何正则给加上""呢?

func TestMakeToJsonStr(t *testing.T) {
	str := `{label  :用户 id,searchType:1,hide:1,disabled:1,required:1,options:1:yes:tag-info,2:no:tag-danger}`
	// 替换所有空格
	// 处理 key 未加""的内容字段
	replace, _ := gregex.Replace(`\s`, []byte(""), []byte(str))
	replace, _ = gregex.Replace(`label|"label"`, []byte(`"label"`), replace)
	replace, _ = gregex.Replace(`fieldType|"fieldType"`, []byte(`"fieldType"`), replace)
	replace, _ = gregex.Replace(`searchType|"searchType"`, []byte(`"searchType"`), replace)
	replace, _ = gregex.Replace(`editHide|"editHide"`, []byte(`"editHide"`), replace)
	replace, _ = gregex.Replace(`addHide|"addHide"`, []byte(`"addHide"`), replace)
	replace, _ = gregex.Replace(`hide|"hide"`, []byte(`"hide"`), replace)
	replace, _ = gregex.Replace(`disabled|"disabled"`, []byte(`"disabled"`), replace)
	replace, _ = gregex.Replace(`required|"required"`, []byte(`"required"`), replace)
	replace, _ = gregex.Replace(`comment|"comment"`, []byte(`"comment"`), replace)
	replace, _ = gregex.Replace(`options|"options"`, []byte(`"options"`), replace)
	// 处理值未加个""的字段
	fmt.Println(string(replace))
}

现在的执行结果

{"label":用户 id,"searchType":1,"hide":1,"disabled":1,"required":1,"options":1:yes:tag-info,2:no:tag-danger}

注明 键就是那几个是固定的

2997 次点击
所在节点    程序员
35 条回复
ericmzhu
2022-07-25 12:47:49 +08:00
我觉得自己先解析字符串为 Json Data ,在输出成 string 好弄点
ysc3839
2022-07-25 15:48:06 +08:00
感觉原数据挺规整的,自己写个解析器也不难吧?网上有许多 JSON 解析器的教程,跟着写一个就好了。
FYFX
2022-07-25 16:23:29 +08:00
我感觉也是写个 parser 比较好,用正则处理多重嵌套和换行感觉容易出问题,看描述大概也就写个 tokenizer ,然后对 token 判断一下类型确认是否加双引号就行
joesonw
2022-07-25 18:20:49 +08:00
/([\w\d_]+\s*\:/
wxf666
2022-07-25 19:15:20 +08:00
@lmshl
@ericmzhu
@ysc3839
@FYFX

编译原理新手求问,你们咋写词法和语法分析呢?


比如下面这条,你们词法分析结果是啥呢?

{options:1:yes:tag-info,2:no:tag-danger}


这样吗?

<{,左括号><options,关键字><:,冒号><1,数字><:,冒号><yes,字符串>……<},右括号>


那你们文法咋写呢?

1. 键值对 ::= 关键字 ":" 『???』

2. 多个键值对 ::= 键值对 | 键值对 "," 多个键值对

3. 对象 ::= "{" 多个键值对 "}"
FYFX
2022-07-25 20:26:11 +08:00
@wxf666 按照 OP 说法,它这个是关键字固定的,而且 options 是特殊的其实应该在写 tokenizer 的时候做处理,应该是 5 个 token, "{","options",":","1:yes:tag-info,2:no:tag-danger","}",解析到 options 的时候做个特殊处理,在碰到下个关键字或者右花括号之前的塞到一个 token ,后面在 parser 再解析吧(也可以这步解析完作为一个特殊的 token),然后文法就和普通的 json 差不多了 ,大概长这样吧
object ::= "{" member ("," member )* "}"
member ::= keyword ":" (object|primary) | "options": options_value
options_value ::= number ":" string ("," number":"string)*
keyword ::= label|searchType|...
primary ::= number|string
我其实也是新手,最近在看 craftinginterpreters
wxf666
2022-07-25 21:18:27 +08:00
@FYFX 词法分析有上下文相关的吗?
FYFX
2022-07-25 21:37:59 +08:00
@wxf666 因为这不是规范的 json ,正常来讲这段应该是在两个引号直接的字符串,我只是觉得这么做后面 paser 写起来会简单点,当然你也可以在 paser 阶段把 options 后面那段拼起来
wxf666
2022-07-26 06:08:21 +08:00
@FYFX 我这方面没啥经验。但总感觉,你的『解析 options 的值』这个步骤,适合放到语法分析中


如你所说,『在碰到下个<keyword, 关键字>或者<}, 右花括号>之前……』,

即『在碰到两种 Token 之前……』?


另外,放到语法分析中,后续若想解析成 下列形式,也更容易些?(可扩展性强些?)

1. {"options": {"1": "a:aa", "2": "b:bb"}}

2. {"options": ["1:a:aa", "2:b:bb"]}


好吧,如果放到词法分析中,要打算用啥方法解析 Token 呢?

NFA/DFA ?应该不够用吧(也就是,三型文法的正则表达式,无法胜任了)

LL/LR/SLR/LALR ?(我瞅瞅去)
FYFX
2022-07-26 09:59:34 +08:00
@wxf666 我只手写过 Scanner ,也就一个 while 循环从头扫到尾 http://www.craftinginterpreters.com/scanning.html
lmshl
2022-07-26 11:50:40 +08:00
我写了一堆电子垃圾,勉强能解析但应该无法适应更多情况了,建议批判就行,别学
面对这种数据格式,我建议打爆数据上游的狗头,让它改成标准 JSON 输出

@wxf666

https://gist.github.com/mingyang91/06f4a489c313a16b9285dd375a565808
wxf666
2022-07-26 17:38:13 +08:00
@lmshl 瞅了瞅,没用过 scala ,只能大概看得懂

这是扩展了自带正则库的文法规则,其递归下降去匹配?

int 、bool 、double 、string 是词法分析,其余是语法分析?(感觉全说成是语法分析也无不可?)

全部是三型文法?(因为没有递归?如:options ::= "options" ":" (options_tuple ("," options_tuple)* | options))

也是高度依赖 tuple 有明确不同于其他文法的规则(要是 {options: opt1: val1, opt2: val2, label: user_id} 就完蛋了)


估计上游不好好用 json 库,自己手动拼接去了,真的是搞事情
lmshl
2022-07-26 17:46:17 +08:00
@wxf666 可以有递归,但是它这个文法里数组没有起止符,会和其他规则有冲突,如果是写标准 JSON parser 的话,代码能比这还少。
最妖孽的就是他给的这个 options
wxf666
2022-07-26 20:31:27 +08:00
@lmshl 懂的,都用递归下降了,肯定可以支持递归文法嘛

上条回复我是说,你当前代码里,没有用到递归文法,所以应该是三型文法

仅从『是否匹配』角度说,是可用『正则表达式』描述 你的文法 的(每个文法的结果处理函数就算了)
morri
2022-07-26 23:43:33 +08:00
@wxf666 @lmshl @FYFX @sutra
大佬们都厉害,向你们学习~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/868341

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX