最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Regex remove json property - Stack Overflow

programmeradmin8浏览0评论

I'd like to remove a stringfied json's property based on its key wherever it is, whatever its value type is. But removing it only if its value is a string and its on the root level of the object would be nice for a beggining. I tried this:

[,]{1}[\s]*?\"attrName\"[ ]*?[:][ ]*?\".*\"[^,]|\"attrName\"[ ]*?[:][ ]*?\".*\"[,]{0,1}

Example :

but it looks a lot big to do such a simple job, what it does is ensure the ma will be removed as well, if attrName is the first attribute, the last ot something in the middle of the json three. Does anyone has a better idea to make this regex more readable?

I'd like to remove a stringfied json's property based on its key wherever it is, whatever its value type is. But removing it only if its value is a string and its on the root level of the object would be nice for a beggining. I tried this:

[,]{1}[\s]*?\"attrName\"[ ]*?[:][ ]*?\".*\"[^,]|\"attrName\"[ ]*?[:][ ]*?\".*\"[,]{0,1}

Example : https://regex101./r/PAlqYi/1

but it looks a lot big to do such a simple job, what it does is ensure the ma will be removed as well, if attrName is the first attribute, the last ot something in the middle of the json three. Does anyone has a better idea to make this regex more readable?

Share Improve this question edited Sep 11, 2017 at 17:11 user47589 asked Sep 11, 2017 at 16:50 Leonardo LanaLeonardo Lana 6101 gold badge6 silver badges13 bronze badges 12
  • 6 Why are you trying to use regex to modify JSON from a JS environment? – user47589 Commented Sep 11, 2017 at 16:59
  • 4 var obj = JSON.parse(str); delete obj[attrName]; str = JSON.stringify(obj); – Daniel A. White Commented Sep 11, 2017 at 17:00
  • 4 RegEx can do this, and surely someone will give you the regex (I won't). Don't. There is literally no reason to do this. Regex does not parse strings, merely follows a pattern. Regex can be fooled and while this particular solution could be locktight, it's a terrible and truly senseless habit to get into. I encourage other users to avoid the internet-points and let this user perform the task properly. – Regular Jo Commented Sep 11, 2017 at 17:04
  • 3 Also, why are you doing things like [,]{1} in your regex? Just use ,! – user47589 Commented Sep 11, 2017 at 17:04
  • 3 Absolutely preprocess it. Even if you manage to somehow get this regex to work, in a month you'll have no idea how the regex works, and minor tweaks will take far too much of your time. Write clear code. – user47589 Commented Sep 11, 2017 at 17:20
 |  Show 7 more ments

3 Answers 3

Reset to default 8

If you have any way of using a parser it's a more stable and readable solution. The regex \s*\"attr\" *: *\".*\"(,|(?=\s*\})) should be shorter and better.

Example

Several changes I made to help:

  1. Don't use so many character classes like [,]. If there is only one element in a character class it should be left by itself.
  2. Only use numbered counts when required. Ex: {0,1} is ? and {1} is pointless.
  3. Instead of searching for a ma in the previous line to see if it is the end of a list checking if there is a } following the line allows you to group the conditionals together.
  4. A positive lookahead is used at the end to search for } so it wouldn't be removed during the substitution.

Update with bugfix mentioned in ments. Trailing mas would be left if the attribute is last. The simplest way I found to fix this was to match both cases. So, you'll have to fill in attr twice.

(,\s*\"attr\" *: *\".*\"|(?=\s*\}))|(\s*\"attr\" *: *\".*\"(,|(?=\s*\})))

Examples with added tests cases

I modified the regex from the first example, it works better even if is Flat JSON

\s*\"attr\" *: *(\"(.*?)\"(,|\s|)|\s*\{(.*?)\}(,|\s|))

Example

Corrected the previous two answers :D

All json syntax consists of quotes, colons and mas. We need to focus on these symbols.

First of all, we need an unescaped quote:

(?<!\\)(?:\\\\)*['"]

The object key in JSON is always a JSON string. A Json string has the following signature: any content wrapped in two identical unescaped quotes:

(?<!\\)(?:\\\\)*('|").*?(?<!\\)(?:\\\\)*\1

Now let's move on to the object: there are three signatures for an object property:

  1. { property: value } - property\s*:\s*value?=\s*\}

  2. { ..., property: value } - ,\s*property\s*:\s*value - ma at the beginning

  3. { property: value, ... } - property\s*:\s*value\s*, - ma at the end

Please note that all tokens can be separated by spaces and line breaks - \s*.

We bine all three cases and get the following expression:

(,\s*property\s*:\s*value)|(property\s*:\s*value(,|(?=\s*\})))

Now we substitute a certain property and value into this signature, where the property is the string attr, and the value is any string:

(,\s*(?<!\\)(?:\\\\)*('|")attr(?<!\\)(?:\\\\)*\2\s*:\s*(?<!\\)(?:\\\\)*('|").*?(?<!\\)(?:\\\\)*\3)|((?<!\\)(?:\\\\)*('|")attr(?<!\\)(?:\\\\)*\5\s*:\s*(?<!\\)(?:\\\\)*('|").*?(?<!\\)(?:\\\\)*\6(,|(?=\s*\})))

This solution will work exactly as you expect. The two previous answers work in a similar way, but contain many errors.

https://regex101./r/3GKXAs/1

发布评论

评论列表(0)

  1. 暂无评论