Extract and Create Property in JSON file with RegEx - json

I have the following JSON file. Dotted across the file is the following:
"properties": {
"Name": "Darlington",
"Description": "<br><br><br> <table border=\"1\" padding=\"0\"> <tr><td>CCGcode</td><td>00C</td></tr> <tr><td>CCGname_short</td><td>Darlington</td></tr>"
}
Using RegEx, I would like to extract the CCG Code property and add it back in so that the above becomes:
"properties": {
"Name": "Darlington",
"CCGcode": "00C",
"Description": "<br><br><br> <table border=\"1\" padding=\"0\"> <tr><td>CCGcode</td><td>00C</td></tr> <tr><td>CCGname_short</td><td>Darlington</td></tr>"
}
I've tried all sorts and I just can't get it to work. I am using Sublime Text.
^("Description":").*?<td>CCGcode<\/td><td>([^<>\n]*).*$
The above selects the code, but not sure how I can get it to create the property.

Try this
( *)"Description".*?CCGcode.*?<td>([^<]+)
Regex demo
This one for sublimetext3
Find what:
( *)("Description".*?CCGcode.*?<td>)([^<]+)
Replace with:
\1"CCGcode": "\3",\n\1\2
Demo

There's a very simpel, but not so elegant, solution. Replace
"Description":.*?<td>CCGcode<\/td><td>([A-Z\d]*)<\/td>
with
"CCGCode":"\1",\n \0
Don't know how Sublime handles replacements, but you may have to change the replacing \0 and \1 to something else - e.g. $0 and $1.
What it does is to find the Description entry and the following CCGCode entry, capturing the code into capture group 1.
Then replace capture group 0 - the whole matched text, with the new CCGCode JSON tag plus the original text.
It's a pretty fragile solution, but it works for your sample case.
Check out example at regex101.
Regards

Related

How to use regex (regular expressions) in Notepad++ to remove all HTML and JSON code that does not contain a specific string?

Using regular expressions (in Notepad++), I want to find all JSON sections that contain the string foo. Note that the JSON just happens to be embedded within a limited set of HTML source code which is loaded into Notepad++.
I've written the following regex to accomplish this task:
({[^}]*foo[^}]*})
This works as expected in all the input that is possible.
I want to improve my workflow, so instead of just finding all such JSON sections, I want to write a regex to remove all the HTML & JSON that does not match this expression. The result will be only JSON sections that contain foo.
I tried using the Notepad++ regex Replace functionality with this find expression:
(?:({[^}]*?foo[^}]*?})|.)+
and this replace expression:
$1\n\n$2\n\n$3\n\n$4\n\n$5\n\n$6\n\n$7\n\n$8\n\n$9\n\n
This successfully works for the last occurrence of foo within the JSON, but does not find the rest of the occurrences.
How can I improve my code to find all the occurrences?
Here is a simplified minimal example of input and desired output. I hope I haven't simplified it too much for it to be useful:
Simplified input:
<!DOCTYPE html>
<html>
<div dat="{example foo1}"> </div>
<div dat="{example bar}"> </div>
<div dat="{example foo2}"> </div>
</html>
Desired output:
{example foo1}
{example foo2}
You can use
{[^}]*foo[^}]*}|((?s:.))
Replace with (?1:$0\n). Details:
{[^}]*foo[^}]*} - {, zero or more chars other than }, foo, zero or more chars other than } and then a }
| - or
((?s:.)) - Capturing group 1: any one char ((?s:...) is an inline modifier group where . matches all chars including line break chars, same as if you enabled . matches newline option).
The (?1:$0\n) replacement pattern replaces with an empty string if Group 1 was matched, else the replacement is the match text + a newline.
See the demo and search and replace dialog settings:
Updates
The comment section was full tried to suggest a code here,
Let me know if this is a bit close to your intended result,
Find: ({.+?[\n]*foo[ \d]*})|.*?
Replace all: $1
Also added Toto's example

VScode - replace captured group with the values

i have a bunch of strings in code such as:
<td style="background-color:#fdfdff"> </td>
and
<td> </td>
in one file.
The goal is to replace from first example with 0, while from second example with - (dash)
I'm using VScode regex, but I can't find the way to replace captured groups with specific values, as $1, $2 groups refer to original string groups.
This one is just example, how I'm trying to achieve this, but VScode don't ignore grouped regex.
An alternative process is to use a snippet which can do conditional replacements. With this snippet:
"replaceTDs": {
"prefix": "tdr", // whatever prefix you want
"body": [
"${TM_SELECTED_TEXT/(?<=\">)( )|( )/${1:+0}${2:+-}/g}",
]
}
The conditional replacements can be quite simple since you first find and select only the two alternative texts you are interested in. So
find: <td\s*(style="[^"]*"\s*)> </td>|<td> </td> old version
This simpler find will probably work for you:
<td\s*(style="[^"]*")?\s*> </td>
Don't replace, rather Control+Shift+L : selects all your two alternatives. Esc to focus on editor from the find widget.
Then apply your snippet, in this case type tdr+Tab
and all the changes are made. You just have to make the snippet one time and then do a single find.
This technique scales a little better than running as many find/replaces as you have replacements to do. Even with more conditional replacements it would probably be a simple change to the one snippet to add more replacements.
Also you can simplify this even more if you use a keybinding to trigger your snippet (you don't have to change focus from the find widget - or create the separate snippet). So with no snippet, but this keybinding:
{
"key": "alt+w",
"command": "editor.action.insertSnippet",
"args": {
"snippet": "${TM_SELECTED_TEXT/(?<=\">)( )|( )/${1:+0}${2:+-}/g}"
},
"when": "editorHasSelection"
}
now the same demo:
You can use
Search for (?<=<td\s+style="[^"]*">) (?=</td>) and replace with 0, and
Search for <td> </td> and replace with <td>-</td>, no need for a regex here.
Note that capturing groups are meant to keep captured substrings.
The first pattern matches
(?<=<td\s+style="[^"]*">) - a place in string that is immediately preceded with <td, one or more whitespaces, style=", any zero or more chars other than " and then a >
- a literal string
(?=</td>) - immediately to the right, there must be </td>.

How to match within two lines in JSON using REGEX?

So the JSON is like:
"foo": {
"points": 23.67
},
I'd like a regex to just match 23.67.
I've tried \"foo\":{\"points\":([^}"]*) but it doesn't work.
There are multiple lines which contain "points": so just \"points\":([^}"]*) won't work.
You are ignoring whitespace.
Try this instead:
\"foo\":\s*{\s*\"points\":\s*(\d+(?:\.\d+)?)\s*}
Demo
Your solution does not take into account a few details:
Between "foo": and { there can be spaces.
After { there can be a newline and spaces.
After "points": there can also be spaces.
Between the string to capture (capturing group and "terminating" '}'
there can also be a newline and spaces.
So, including the above missed details, and taking into account that \s
matches also newline, the whole regex can be as follows:
\"foo\":\s*{\s*\"points\":\s*([^}"]*)\s*}
Actually, your capturing group can be "more restrictive".
As the text to capture contains only digits and a dot,
it can be written as: [\d\.]+.
Note that I changed * to +, because the content cannot be empty.

Condense all my snippets into one file in Sublime Text 3

I have a multitude of snippets for each tag in the language I am currently programming in. I want to share these with some of my co-workers but I don't want to send them like 30 snippet files. Is there a way to condense these into one file (apart from zipping them, sending the zip and then having them unzip it).
You can use a .sublime-completions file. These are JSON-formatted files that contain the target scope at the top, then a series of completions with a trigger and contents. For example, the following snippet
<snippet>
<content><![CDATA[function ${1:function_name} (${2:argument}) {
${0:// body...}
}]]></content>
<tabTrigger>fun</tabTrigger>
<scope>source.js</scope>
<description>Function</description>
</snippet>
can be turned into this completion:
{
"scope": "source.js",
"completions":
[
{ "trigger": "fun", "contents": "function ${1:function_name} (${2:argument}) {\n ${0:// body...}\n}" }
]
}
Use \n for newlines and \t for tab characters in the "contents" section. Double quotes need to be escaped as well. Also, you can use \t to separate the trigger from a brief description on what the completion is about, it will be displayed right-aligned and slightly grayed and does not affect the trigger itself:
{ "trigger": "fun\tFunction", "contents": "function ${1:function_name} (${2:argument}) {\n ${0:// body...}\n}" }
Since this is JSON, to add multiple completions just put a comma , after the closing curly brace } of the completion, and put your next one on the next line. The final line should not have a final comma.
Good luck!

JSON string data display with breaks?

So I'm creating a game for work, which grabs question and answer data from a JSON file that someone helped me create. All I want to figure out, is how to make the string that is returned from the data below display with line breaks for each of the multiple choice answers:
{
"question": "1",
"text" : "How many times has the Actuarial computer lab been moved? A. Once B. Twice C. Six times D. Fifteen times",
"answer" : "1,1"
},
I've been googling for a while (lots of Stackoverflow threads) but every solution appears to be something different or slightly more complex than what I want to do.
Here is how I'm displaying the string into my div:
var displayDiv = $("#textdisplay");
displayDiv.text(question.text);
You probably want to add <br/> or <p> tags to your text in the JSON file itself. If you've got a text editor that can do regex string replacement, then you want to do something like
Find: ([ABCD]\.\s)
Replace: <br/>$1
Or if you're on a machine with sed, you can use
sed -E 's/([ABCD]\. )/<br\/>\1/g' test.txt
That'd be my recommendation, at least. If you can't change the JSON file, use the same Regex to add breaks in JavaScript, like so:
question.text.replace(/([ABCD]\. )/g, '<br/>$1')