A-A+

正则表达式替换json字符串key上的引号办法

2018年08月10日 javascript 暂无评论 阅读 13 views 次

json的格式如下:

{
"a":1,
"b":"sssss",
"c":true
}

通过如下表达式匹配了冒号和key

"([A-Za-z0-9_-]{1,})":

这个表达式是什么意思呢?

1.第一个和最后一个“,是指key被引号包围

2.(和)表示标签区域

这个匹配一个标签区域. 这个标签可以被访问,通过语法 \1访问第一个标签, \2 访问第二个, 同理 \3 \4 … \9。 这些标签可以用在当前正则表达式中,或则替search和replace中的换字符串。

3.[],表示一个字符集合, 例如 [abc]表示任意字符 a, b or c.我们也可以使用范围例如[a-z] 表示所以的小写字母

4. A-Z 所有的大写字母

5.a-z 所有的小写字母

6.0-9 所有的数字

7.-_ 匹配这两个符号

8.{1,}  这里指前面的表达式,至少匹配1次

匹配至少m次,至多n次(如果n缺失,则任意次数).例如, ‘Sa{2,3}m’ 匹配 Saam or Saaam. ‘Sa{2,}m’ 与 ‘Saa+m’相同

9.: 匹配:

整个表达式就是要匹配json的key带上一个冒号


js部分的写法:


var reg=/"([A-Za-z0-9_-]{1,})":/g;
 json.replace(reg,'$1:');

这样就把json  key上的引号去掉了。

有人说,直接用JSON.parse()转一下不就结了吗? 有时候,我们不能用这个东西去转,就只能自己去搞了 

匹配字符串的基本规则

1. 匹配固定的字符串

regex e("abc");

2. 匹配固定字符串,不区分大小写

regex e("abc", regex_constants::icase);

3. 匹配固定字符串之外多一个字符,不区分大小写

regex e("abc.", regex_constants::icase);  // .  Any character except newline. 1个字符

4. 匹配0个或1个字符

regex e("abc?");    // ?  Zero or 1 preceding character. 匹配?前一个字符

5. 匹配0个或多个字符

regex e("abc*");    // *  Zero or more preceding character. 匹配*前一个字符

6. 匹配1个或多个字符

regex e("abc+");    // +  One or more preceding character. 匹配+前一个字符

7. 匹配特定字符串中的字符

regex e("ab[cd]*");    // [...] Any character inside square brackets. 匹配[]内的任意字符

8. 匹配非特定字符串的字符

regex e("ab[^cd]*");    // [...] Any character not inside square brackets. 匹配非[]内的任意字符

9. 匹配特定字符串,且指定数量

regex e("ab[cd]{3}");    // {n}  匹配{}之前任意字符,且字符个数为3个

10. 匹配特定字符串,指定数量范围

?
1
2
regex e("ab[cd]{3,}"); // {n} 匹配{}之前任意字符,且字符个数为3个或3个以上
regex e("ab[cd]{3,5}"); // {n} 匹配{}之前任意字符,且字符个数为3个以上,5个以下闭区间

11. 匹配规则中的某一个规则

regex e("abc|de[fg]");    // |  匹配|两边的任意一个规则

12. 匹配分组

regex e("(abc)de+");    // ()       ()表示一个子分组

13. 匹配子分组

?
1
2
regex e("(abc)de+\\1"); // ()    ()表示一个子分组,而\1表示在此位置匹配第一个分组的内容
regex e("(abc)c(de+)\\2\\1"); // \2 表示的是在此匹配第二个分组的内容

14. 匹配某个字符串开头

?
1
2
regex e("^abc.");
// ^ begin of the string 查找以abc开头的子字符串

15. 匹配某个字符串结尾

?
1
2
regex e("abc.$");
// $ end of the string 查找以abc结尾的子字符串

      以上是最基本的匹配模式的书写。通常如果要匹配特定的字符,需要使用\进行转义,比如在匹配字符串中需要匹配".",那么在匹配字符串中应该在特定字符前加上\。出了以上的基本规则,如果还不满足特定的需要,那么可以参考此链接。使用了解基本的匹配模式后,需要使用正则表达式进行匹配、查找或者替代。

正则匹配、查找与替代

      书写好模式字符串后,需要将待匹配的字符串和模式字符串进行一定规则的匹配。包括三种方式:匹配(regex_match)、查找(regex_search)、替换(regex_replace)。

      匹配很简单,直接将待匹配字符串和模式字符串传入到regex_match中,返回一个bool量来指明待匹配的字符串是否满足模式字符串的规则。匹配整个str字符串。

?
1
2
bool match = regex_match(str, e);
// 匹配整个字符串str

      查找是在整个字符串中找到和满足模式字符串的子字符串。也就是只要str中存在满足模式字符串就会返回true。

?
1
2
bool match = regex_search(str, e);
// 查找字符串str中匹配e规则的子字符串

      但是很多情况下,光是返回一个是否匹配的bool量是不够的,我们需要拿到匹配的子字符串。那么就需要在模式字符串中将匹配字符串分组,参考【匹配字符串的基本规则】第12点。再将smatch传入到regex_search中,就可以获得满足每个子分组的字符串。

?
1
2
3
4
5
6
smatch m;
bool found = regex_search(str, m, e);
for(int n = 0; n < m.size(); ++n)
  {
    cout <<"m["<< n <<"].str()="<< m[n].str() << endl;
  }

    替换也是基于模式字符串在分组情况下完成的。

?
1
cout << regex_replace(str, e,"$1 is on $2");

      此时,会在满足分组1和分组2的字符串中间加上“ is on”。

      以上三个函数有很多版本的重载,可以满足不同情况下的需求。

实战

      要求:找出满足sectionA("sectionB")或者sectionA ("sectionB")的模式字符串。且分离出sectionA、sectionB。sectionA和sectionB不会出现数字,字符可大小写,至少有一个字符。

      分析:根据要求,大致可分为两个部分,也就是sectionA和sectionaB。这是就需要用到分组。

第一步:写出满足section情况的模式字符串

[a-zA-Z]+

第二步:在sectionA和sectionB中可能会出现空格。暂且假设至多有1个空格

\\s?

将以上两个情况组合起来,也就是能满足我们需求的模式字符串。但是如何组织才能让其分为两组呢?

[a-zA-Z]+\\s[a-zA-Z]+

上面这种写法肯定不对的,根据分组规则,需要将分组以()进行区分

regex e("([a-zA-Z]+)\\s?\\(\"([a-zA-Z]+)\"\\)");

      此时,在\\s?后面的\\(\"是为了满足sectionB外层的引号和括号进行的转义。

      以上完成后,可先用regex_match进行匹配,如果匹配,那么继续使用regex_search对字符串进行查找

?
1
2
3
4
5
6
7
8
9
10
11
12
13
if(regex_match(str, e))
{
 smatch m;
 auto found = regex_search(str, m, e);
 for(int n = 0; n < m.size(); ++n)
 {
 cout <<"m["<< n <<"].str()="<< m[n].str() << endl;
 }
}
else
{
 cout <<"Not matched"<< endl;
}

      对象m数组的第一个字符串是满足需求的整个子串,接下来才是满足分组1、分组2的子串。

打赏作者
如果文章对您有所帮助请打赏支持本站发展。

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

标签:

给我留言

您必须 登录 才能发表留言!

Copyright © 前端技术分享休闲玩耍去处分享-大一网 保留所有权利.   Theme  Ality

用户登录 ⁄ 注册

分享到: