You can use
const text = 'is:"browser" browser: "chrome 11.11 V" node: error type:"Error"';
const re = /(\w+):\s*(?:"([^"]*)"|(\S+))/g;
let dict = {}, m;
while(m = re.exec(text)) {
dict[m[1]]=(m[3] || m[2]);
}
console.log(dict);
// Or just get all matches:
console.log(text.match(re))
See the regex demo. Details:
(\w+)- Group 1: one or more word chars:- a colon\s*- zero or more whitespaces(?:"([^"]*)"|(\S+))- either of"([^"]*)"-", 0+ non-commas (captured in Group 2),"|- or(\S+)- Group 3: one or more non-whitespaces chars.
You can use
const text = 'is:"browser" browser: "chrome 11.11 V" node: error type:"Error"';
const re = /(\w+):\s*(?:"([^"]*)"|(\S+))/g;
let dict = {}, m;
while(m = re.exec(text)) {
dict[m[1]]=(m[3] || m[2]);
}
console.log(dict);
// Or just get all matches:
console.log(text.match(re))
See the regex demo. Details:
(\w+)- Group 1: one or more word chars:- a colon\s*- zero or more whitespaces(?:"([^"]*)"|(\S+))- either of"([^"]*)"-", 0+ non-commas (captured in Group 2),"|- or(\S+)- Group 3: one or more non-whitespaces chars.
Regex:
/([a-zA-Z!]+:\s*[" ]?([a-z0-9\s.]+)[" $])/gi
Text:
sdfd:"dsffs" dsfd: "dsf demo" sfd: dsf fdsff:"fdsfsdf"
List:
sdfd:"dsffs"
dsfd: "dsf demo"
sfd: dsf
fdsff:"fdsfsdf"
Hi,
Totally new to regex. I've tried asking chatGPT and several regex generators but I cannot figure this out.
I'm trying to extract key value pairs from specifications from a website using javascript.
Assume keys and values alternate, I am pulling the data from a table. Assume if the first character of second word is uppercase it's a key, else it's a value.
Example (raw text):
Machine washable Yes Color Clear Series Share Capacity 123 cl Category Vase Brand RandomBrand Item.nr 43140
Example (paired manually):
Machine washable: Yes Color: Clear Series: Share Capacity: 123 cl Category: Vase Brand: RandomBrand Item.nr: 43140
Is this even possible with regex? I feel lost here.
Thanks for taking the time.
Edit: I will try another approach but Im still curious if this is possible.
regex - Extracting numeric values from a string containing key:value pairs - Code Review Stack Exchange
pcre - Extracting `<key>=<value>` pairs with regex, dot group (.+?) not cooperating with optional space (\s) - Stack Overflow
Returning value from key-value pairs
Regex to match a specific key value pair in Logstash
@acfrancis explanation is correct, on the other hand you can try the following:
/(\w+)=([^\s]+)/g
This matches the <key> using (\w+) as in you original expression, but then it matches the value using ([^\s]+) which consumes one or more characters that are not white spaces.
Regex101 Demo
Since the \s isn't required, the previous part (.+?) is free to match just one character which is what it will try to do because of the ?. You can either:
- change
(.+?)to(.+)but that might cause other issues if your values can include spaces or - change
\s?to(?:\s|$)
I currently have this string:
year=2022 | month=March| date=11 | day=Friday| time=1:00 AM
Been struggling with creating a regex to retrieve the value from the key-value pairs for each: year, month, date, day, time. Any suggestions on how to approaching this particular regular expression? Currently trying to build this in Adobe Analytics using the Classification Rule Builder. Thank you!
Try with a lookahead:
(\b\w+)=(.*?(?=\s\w+=|$))
As a Java String:
"(\\b\\w+)=(.*?(?=\\s\\w+=|$))"
Test at regex101.com; Test at regexplanet (click on "Java")
\1 contains the key and \2 the value:
(key\d+)=(.*?)(?= key\d+|$)
Escape \ with \\ in Java:
(key\\d+)=(.*?)(?= key\\d+|$)
Demo: https://regex101.com/r/dO8kM2/1
Assuming that you either have a word like ActiveList or something in bewteen <> you could is this reg exp:
\s*(\w+)\s*=\s*(\w+|<.*?>)\s*
First group will capture the attr name and second will capture a word (ActiveList) or anything between <> like <Resource URI\="/All Active Lists/_CAL/Infrastructure/Active Directory/Inventory/Inventory - By User (Bobo)" ID\="CCCsSSdDDD\=\="/>
Then, you just need to iterate over results and join them with =:
>>> for attr, value in re.findall("\s*(\w+)\s*=\s*(\w+|<.*?>)\s*",text):
print "%s=%s" % (attr, value)
attr1=ActiveList
attr2=<Resource URI\="/All Active Lists/_CAL/Infrastructure/Active Directory/Inventory/Inventory - By User (Dedd)" ID\="DSdddCcSSS\=\="/>
attr3=ActiveLis
attr4=ActiveList
attr5=<Resource URI\="/All Active Lists/_CAL/Infrastructure/Active Directory/Inventory/Inventory - By User (Bobo)" ID\="CCCsSSdDDD\=\="/>
attr6=ActiveLis
Simply split attr[..]=:
>>> splits = [c for c in re.split('(attr[\d]=)', text) if c]
>>> for y in range(0, len(splits), 2):
... print (splits[y], splits[y+1])
...
attr1= ActiveList
attr2= <Resource URI\="/All Active Lists/_CAL/Infrastructure/Active Directory/Inventory/Inventory - By User (Dedd)" ID\="DSdddCcSSS\=\="/>
attr3= ActiveLis
attr4= ActiveList
attr5= <Resource URI\="/All Active Lists/_CAL/Infrastructure/Active Directory/Inventory/Inventory - By User (Bobo)" ID\="CCCsSSdDDD\=\="/>
attr6= ActiveList
You have a few ways to do this. First, since you said your key-value pairs are embedded in a larger email, you need to extract them. You can do that with this regex, which checks for a line starting with a word and an equals sign:
import re
text = " ... Full email text ... "
dataPoints = re.search(r"^\w*=.*$", text, re.MULTILINE).group(0)
Then you need to create your dictionary.
Option 1: Simplest
Use the following regex find:
result = dict(re.findall(r'(\w*)=(\".*?\"|\S*)', dataPoints))
Regex demo
Option 2: Typical split
Follow the typical method for this problem: split the various key-value combinations into a list, and then split each combination into separate keys and values. However, since your key-value pairs are separated by spaces rather than semicolons, ampersands, or something similar, and some of your values have spaces in them, we can't simply split by spaces. That means we need to use a regex lookahead for this to work properly:
regexSplit = dict([i.split("=") for i in re.split(r"\s(?=\w+=)", dataPoints)])
Option 3: No regex
If you want to avoid using regex altogether for whatever reason, you can use the following, which splits on equals signs and then recombines the keys and values into the proper arrangement for creating a dictionary:
allSplits = dataPoints.split("=")
splitList = [allSplits[0]] + [i for a in allSplits[1:-1]
for i in a.rsplit(" ", 1)] + [allSplits[-1]]
splitDict = dict(zip(splitList[::2], splitList[1::2]))
The code above assumes your dictionary will end up with at least 2 items.
Demo for all 3 options
What about adding an OR (|) to your regex, e.g.
(\w*)=(\"[\w\s\+()\.]*\"|[\w\-\:\.]*)
matches the string you gave.
Note
\"[\w\s\+()\.]*\"matches all the values enclosed in""[\w\-\:\.]*matches the ones without