Creating a custom regex script in Javascript to properly parse Google Sheets data that contains commas

Currently, I am working with a JavaScript script that extracts data from a public Google Sheets feed in a JSON-CSV format that requires parsing.

The rows are separated by commas, but the challenge lies in dealing with unescaped commas within each item. For example:

"a: Feb 21, 10:11, b: some content, c: more, d: even more"

My objective is to achieve the following structure:

{
  "a": "Feb 21, 10:11",
  "b": "some content",
  "c": "more",
  "d": "even more"
 }

Initial Splitting Attempt

Executing data.split(',') results in:

{
  "a: Feb 21,
  "10:11",
  "b some content",
  "c: more",
  "d: even more"
 }

Regex Experimentation

I have tried using the regex pattern: (?[^,]+): (?[^,]+), which almost accomplishes the task of wrapping the comma around a date value at the beginning of the next property occurrence.

Referenced Image - View on Regex101

Answer №1

Refer to the UPDATE below for a fresh response.


The given result is not definitive, as a comma might be part of a cell or act as a separator without clear distinction.

If JSON isn't preferred, converting a sheet to .csv format can be done in the following way:

  • Choose the intended sheet to share, like Sheet2
  • Select Comma-separated values (.csv) as the format

This action allows access to the CSV data using the URL:

https://docs.google.com/spreadsheets/d/e/<spreadsheet-id>/pub?gid=<tab-id>&single=true&output=csv

An example sheet:

| A1 cell   | B1 |
| A2, content | B2 |

Sample CSV output:

A1 cell,B1
"A2, content",B2

Various tools are handy for parsing CSV files, such as https://github.com/peterthoeny/parse-csv-js


UPDATE, considering Esteban's limitation from altering the data source:

To generate the desired object, utilize split and forEach methods as shown below:

const input = 'a: Feb 21, 10:11, b: some content, c: more, d: even more';
let result = {};
input.split(/, (?=[a-z]+:)/)
.forEach(item => {
  let key = item.replace(/:.*/, '');
  let val = item.replace(/.*?: */, '');
  result[key] = val;
});
console.log(JSON.stringify(result, null, ' '));

Result:

{
 "a": "Feb 21, 10:11",
 "b": "some content",
 "c": "more",
 "d": "even more"
}

Explanation:

  • let result = {}; - initializes an empty object called result
  • .split(/, (?=[a-z]+:)/) - splits based on key/value pairs with a lookahead for an alphabet: key
  • .forEach():
    • extracts the key and value from each item
    • adds a new property to result object, with the property name being the key

Answer №2

Check out this approach:

(?<tag>\w+): (?<value>.+?)(?:,(?= \w+:)|$)

Demo & breakdown

Answer №3

If the text in cell A2 is taken as a sample string, you can experiment with this formula:

=SPLIT(REGEXREPLACE(" "&A2,",\s([\w]+[\d]*:)","|$1"),"|")

To explain the REGEX in simple terms: "Locate a comma followed by a space, then some word characters possibly ending with a single digit before another comma. When found, replace the initial comma and space with a pipe symbol while leaving everything else unchanged."

The SPLIT function will be applied to that pipe symbol.

A leading space is included at the start of the entire string so that we can pinpoint a "space followed by a comma" for the first label.

Answer №4

Give this a shot:

(?[^,\s]+): (?.+:\d\d|[^,]+)

The important thing to remember is to utilize the pipe symbol as an alternative option that first searches for the specific date-time format and then the rest of the content (the initial pattern you were working with).

When testing your regex in the builder on regex101, it should appear like this:

https://i.sstatic.net/FN0Sq.jpg

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to display the data within a BLOB object

On this page, the user is showcasing a table with three columns - tipo_esame (string), data_esame (string), and uri (BLOB). const archiveItems = this.state.archive.map((archive, i) => { return ( <tr key={archive.hash_referral}> <td ...

Parsing a JSON object using JSON.NET

Hi there, I am encountering an issue that I can't seem to solve. I need help extracting values from the JSON Object in a web method. ASPX Code $(document).ready(function () { // Add the page method call as an onclick handler for the div ...

Is it possible to invoke this JavaScript function like this?

Is there a way to call a function like item_edit.say hello by passing it as a string on the window object (similar to the last line in the snippet below)? var arc={ view: { item_edit: {} } }; arc.view.item_edit={ say_hello: function(){ alert(' ...

Optimizing Shader Caching in WebGL: Best Practices

I am currently in the process of developing a WebGL application, and I have encountered some challenges with shader storage... In most examples, shaders are directly written in plaintext within the xHTML file itself. However, this approach can lead to clu ...

Flask response fails to retain non-visible characters in string

My Python string variable has a unique format: '\x1d0103671286378126378127812\x1d1232321102I009B\x1d71012321271' When I send it in a json response, the \x1d characters disappear. Strangely enough, when I print it on the con ...

Unlinking styles from the template in Vue.js

I have a unique situation where my template contains a <style> block that needs to be positioned near its corresponding div due to CMS restrictions. However, when I try to integrate Vue.js into the mix, it appears to strip out the style block and di ...

Create a new JSON file and add data using ObjectMapper

My current project involves delving into Jackson to gain a better understanding of how it works. I am in the process of creating a simple program that can both read from and write to a file, specifically storing JSON data in it. This project revolves aroun ...

Tips on extracting information from several JSON response objects

I have the following ArrayList: JSONArray JMyDataList= new JSONArray(MyDataList); JSONArray JMyProjectData = new JSONArray(MyProjectData); MyDataList: contains data retrieved from a database with column names and data. response.setConten ...

javascript conceal other sections upon hovering

There are 4 list items (<li>) that I want to use as triggers for linked images. In this project, I am using vanilla JavaScript as jQuery is not allowed. Below is the code snippet: var children = document.querySelectorAll('#resistorContent > ...

Transform JSON data into JPA entities under the management of Jackson

When unmarshalling a JPA entity annotated with @Entity using Jackson, I want Jackson to operate on an already managed instance if one exists, deserializing all its properties; otherwise, create a new transient instance. Let's say there is a Person en ...

Is concealing content using Javascript or jQuery worth exploring?

While I have been hiding content using display:none; in css, there are concerns that Google may not like this approach. However, due to the needs of jQuery animations, it has been necessary for me. Recently, I have come across a new method for hiding conte ...

Displaying HTML with extracted message form URL

I have a link that redirects to this page Is there a way for me to extract the message "Message Sent Successfully" from the URL and display it in the form below? <form action="send_form_email.php" name="contactForm" method="post"> //I want to d ...

The JSON object is not providing the length of the array, returning the value as

I'm currently fetching JSON data from a PHP file in the following manner: $.getJSON('fresh_posts.php',function(data){ global_save_json = data.freshcomments; var countPosts = data.freshposts; var howManyPosts = countPosts.length; ...

The JSON object is coming back as null

I need some clarification on why I am getting an "undefined" alert. Any assistance you can offer would be greatly appreciated as this problem is holding up progress on a crucial project. JavaScript $.getJSON("item-data.json", function(results) { ...

The Vue ChartJS fails to display properly after the page is refreshed

Although this issue may appear to be a common one, some of the suggested solutions are outdated or no longer functional. My objective is to ensure that the chart remains responsive even after the page reloads. I attempted to implement the solution provided ...

Retrieving the size of every image with ajax while also storing extra image information

In my current project, the objective is to iterate through all images on a webpage and collect various details such as image name, original dimensions, actual size, ratio, display property, and FILESIZE. However, I have encountered a hurdle in my progress ...

Displaying PHP output within a JavaScript expression

Let's dive into a scenario involving a basic HTML document and some JavaScript that's loaded within it: <!-- doc.html --> <!doctype html> <html lang="en"> <head> <script type="text/javascript" src=" ...

What is the prescribed interface or datatype for symbol type in TypeScript with JavaScript?

I have a set of symbol values in JavaScript that I want to convert to TypeScript. // Defining object values in JavaScript const size = { Large: Symbol('large'), Medium: Symbol('medium') } What is the most efficient method to conv ...

Fetching deeply nested data from JSON within Angular Material tables - ANGULAR

Having trouble retrieving data from localhost, especially when it's in a different structure. Any suggestions on how to properly extract and display this data for the user? This is my attempted approach, but I'm encountering an error message: ER ...

What is the best way to differentiate between two calls to the same method that are based on different arguments?

Currently, I am utilizing sinon to mock functions from Google Drive in my NodeJS project. In a single test scenario, I make two separate calls to the create method (without the ability to restore between calls): // Call 1: drive.files.create({ 'reques ...