Find values using regex (includes brackets)

Viewed 64

it's my first time with regex and I have some issues, which hopefully you will help me find answers. Let's give an example of data:

chartData.push({
date: newDate,
visits: 9710,
color: "#016b92",
description: "9710"
});
var newDate = new Date();
newDate.setFullYear(
2007,
10,
1 );

Want I want to retrieve is to get the date which is the last bracket and the corresponding description. I have no idea how to do it with one regex, thus I decided to split it into two.

First part:

I retrieve the value after the description:. This was managed with the following code:[\n\r].*description:\s*([^\n\r]*) The output gives me the result with a quote "9710" but I can fairly say that it's alright and no changes are required.

Second part:

Here it gets tricky. I want to retrieve the values in brackets after the text newDate.setFullYear. Unfortunately, what I managed so far, is to only get values inside brackets. For that, I used the following code \(([^)]*)\) The result is that it picks all 3 brackets in the example:

"{
date: newDate,
visits: 9710,
color: "#016b92",
description: "9710"
}",
"()",
"2007,
10,
1 "

What I am missing is an AND operator for REGEX with would allow me to construct a code allowing retrieval of data in brackets after the specific text.

I could, of course, pick every 3rd result but unfortunately, it doesn't work for the whole dataset.

Does anyone of you know the way how to resolve the second part issue?

Thanks in advance.

3 Answers

You can use the following expression:

res = re.search(r'description: "([^"]+)".*newDate.setFullYear\((.*)\);', text, re.DOTALL)

This will return a regex match object with two groups, that you can fetch using:

res.groups()

The result is then:

('9710', '\n2007,\n10,\n1 ')

You can of course parse these groups in any way you want. For example:

date = res.groups()[1]
[s.strip() for s in date.split(",")]

==> 
['2007', '10', '1']
import re

test = r"""
    chartData.push({
        date: 'newDate',
        visits: 9710,
        color: "#016b92",
        description: "9710"
    })
    var newDate = new Date()
    newDate.setFullYear(
        2007,
        10,
        1);"""

m = re.search(r".*newDate\.setFullYear(\(\n.*\n.*\n.*\));", test, re.DOTALL)


print(m.group(1).rstrip("\n").replace("\n", "").replace(" ", ""))

The result:

(2007,10,1)

The AND part that you are referring to is not really an operator. The pattern matches characters from left to right, so after capturing the values in group 1 you cold match all that comes before you want to capture your values in group 2.

What you could do, is repeat matching all following lines that do not start with newDate.setFullYear(

Then when you do encounter that value, match it and capture in group 2 matching all chars except parenthesis.

\r?\ndescription: "([^"]+)"(?:\r?\n(?!newDate\.setFullYear\().*)*\r?\nnewDate\.setFullYear\(([^()]+)\);

Regex demo | Python demo

Example code

import re

regex = r"\r?\ndescription: \"([^\"]+)\"(?:\r?\n(?!newDate\.setFullYear\().*)*\r?\nnewDate\.setFullYear\(([^()]+)\);"

test_str = ("chartData.push({\n"
    "date: newDate,\n"
    "visits: 9710,\n"
    "color: \"#016b92\",\n"
    "description: \"9710\"\n"
    "});\n"
    "var newDate = new Date();\n"
    "newDate.setFullYear(\n"
    "2007,\n"
    "10,\n"
    "1 );")

print (re.findall(regex, test_str))

Output

[('9710', '\n2007,\n10,\n1 ')]

There is another option to get group 1 and the separate digits in group 2 using the Python regex PyPi module

(?:\r?\ndescription: "([^"]+)"(?:\r?\n(?!newDate\.setFullYear\().*)*\r?\nnewDate\.setFullYear\(|\G)\r?\n(\d+),?(?=[^()]*\);)

Regex demo

Related