Can you provide the regular expression that will successfully match this specific string of text?

Can you solve this fruit riddle?

apple is 2kg
apple banana mango is 2kg
apple apple apple is 6kg
banana banana banana is 6kg

If the fruits are limited to "apple", "banana", and "mango", how can we write a regex that extracts the names of the fruits at the beginning of each sentence?

I tried using this regex (https://regex101.com/r/fY8bK1/1):

^(apple|mango|banana) is (\d+)kg$  

However, it only works for sentences with a single fruit. How can we modify it to extract all fruit names from a sentence?

The desired output should be:

apple, 2
apple banana mango, 2
apple apple apple, 6
banana banana banana, 6

Answer №1

To achieve grouping functionality, you can utilize the following pattern:

^((?:dog|cat|rabbit)(?:\s+(?:dog|cat|rabbit))*) weighs (\d+)lbs$

Take a look at the demo of this regex.

The purpose of using (?:...) is to avoid capturing unnecessary groups within the main capturing group ((...)) and maintain simplicity in the results.

The

((?:dog|cat|rabbit)(?:\s+(?:dog|cat|rabbit))*)
section matches:

  • (?:dog|cat|rabbit) - any option from the given list separated by the alternation operator |. If you want to match complete words only, add \b at both ends of the subpattern.
  • (?:\s+(?:dog|cat|rabbit))* matches zero or more occurrences of...
    • \s+ - one or more spaces
    • (?:dog|cat|rabbit) - any of the listed options.

Example Usage:

var re = /^((?:dog|cat|rabbit)(?:\s+(?:dog|cat|rabbit))*) weighs (\d+)lbs$/gm; 
var str = 'dog weighs 10lbs\n cat dog rabbit weighs 5lbs\ncat cat cat cat weighs 20lbs';
var data;
 
while ((data = re.exec(str)) !== null) {
    document.write(data[1] + "," + data[2] + "<br/>");
}

document.write("<b>catcat weighs 15lbs</b> matched: " + 
     /^((?:dog|cat|rabbit)(?:\s+(?:dog|cat|rabbit))*) weighs (\d+)lbs$/.test("catcat weighs 15lbs"));

Answer №2

Give this a try

var regex = /^((?:(?:orange|pear|kiwi)(?= ) ?)+) is (\d+)kg$/gm;

regex.exec('orange pear kiwi is 3kg');
// ["orange pear kiwi is 3kg", "orange pear kiwi", "3"]

What sets this solution apart from the rest? The (?= ) ? section following the fruit choices ensures there is a space before the weight, without capturing it unless more fruits follow (or there is extra spacing before the "is").

Click here for a visual breakdown of the regex pattern.

Implement this within a while loop to extract all matches from a multiline text block.


The gm flags enable the regular expression to be executed multiple times on the same string using regex.exec, with newline characters matching $^. With that said, the behavior changes when using the g flag with str.match.

If you prefer to test each string independently, you can maintain the original regex pattern without the global and multiline flags, or switch to str.match without any flags.

var regex = /^((?:(?:orange|pear|kiwi)(?= ) ?)+) is (\d+)kg$/; // without flags

'orange pear kiwi is 3kg'.match(regex);
// ["orange pear kiwi is 3kg", "orange pear kiwi", "3"]

Answer №3

/^(((kiwi|pineapple|pear)\s*)+) weighs (\d+)kg$/$1,$4/gm

DEMO: https://regex101.com/r/pT6bY8/3

To start, you can choose one of the following fruits:

(kiwi|pineapple|pear)

Including optional spaces between each fruit:

(kiwi|pineapple|pear)\s*

Then repeat this group at least once:

((kiwi|pineapple|pear)\s*)+

You need to wrap all of these in an additional group for capturing:

(((kiwi|pineapple|pear)\s*)+)

At this point, $1 will hold "pear pear pear ..."; and the fourth match will be your weight. You can avoid capturing inner groups by using ?: if desired. Check it out here.

Answer №4

^((?:apple|mango|banana| )+) weighs (\d+) kilograms\s?$/gmi

DEMO

https://regex101.com/r/dO1rR7/1


Explanation

^((?:apple|mango|banana| )+) is (\d+)kg\s?$/gmi

^ assert position at start of a line
1st Capturing group ((?:apple|mango|banana| )+)
    (?:apple|mango|banana| )+ Non-capturing group
        Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
        1st Alternative: apple
            apple matches the characters apple literally (case sensitive)
        2nd Alternative: mango
            mango matches the characters mango literally (case sensitive)
        3rd Alternative: banana
            banana matches the characters banana literally (case sensitive)
        4th Alternative:  
             matches the character  literally
 weighs matches the characters  weighs literally (case sensitive)
2nd Capturing group (\d+)
    \d+ match a digit [0-9]
        Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
kilograms matches the characters kilograms literally (case sensitive)
\s? match any white space character [\r\n\t\f ]
    Quantifier: ? Between zero and one time, as many times as possible, giving back as needed [greedy]
$ assert position at end of a line
g modifier: global. All matches (don't return on first match)
m modifier: multi-line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)
i modifier: insensitive. Case insensitive match (ignores case of [a-zA-Z])

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

Leveraging Jquery to add an element or text in front of the initial instance of a different element

Here is a sample of my xml code: <entry> <br> <abc></abc> <xyz></xyz> <example></example> <example></example> <example></example> </entry> <entry> <br> <abc>&l ...

The process of handling state in React when it goes live in production

Currently, I am delving into the world of ReactJS as a novice. The intricacies of state management have captivated my interest. A pressing question has surfaced in my mind regarding this topic. Let's consider a scenario - I have developed a React appl ...

How can Components access variables declared in a custom Vue.js plugin?

I had developed a unique Vue js plugin to manage global variables as shown below: CustomConstants.js file: import Vue from 'vue' export default { install(Vue){ Vue.CustomConstants = { APP_VERSION: '2.1.0' ...

Attaching a $UI element to a <div> tag with JQuery may result in unexpected errors and issues

Attempting to connect SagePayments card elements to the paymentDiv. Followed their sample project for guidance, but encountering issues with populating the elements when running the program with a custom Sandbox merchantID and merchantKey. Chrome's de ...

Difficulty encountered when consolidating intricate data attributes into a single array

I have a task to tackle in the code snippet below. My goal is to collect all the data in the age attributes and store them in a single array, formatting it as shown here: output = [48, 14, 139, 49, 15, 135, 51, 15, 140, 49, 15, 135, 51, 15, 140, 52, 16, ...

Dispatch prop within useEffect

App.js -> <Lobbies inGame={inGame} setLobby={setLobby} userName={userName} userKey={userKey}/> Lobbies.js -> import React, { useState, useEffect } from 'react'; import firebase from 'firebase'; const Lobby = ({userKey, ...

Tips on how to lock the ag-grid to the highlighted row's position and force it to scroll

We have integrated ag-grid into our system, and I am facing an issue with displaying the scrollbar in a child window based on the selected row position in ag-grid. Please refer to the Plunkr link below and click on source_id which will lead you to an edit ...

Discover every possible path combination

Looking to flatten an array of 1D arrays and simple elements, reporting all combinations until reaching a leaf "node." For example: // Given input array with single elements or 1D arrays: let input = [1, 2, [3, 4], [5, 6]]; The unfolding process splits pa ...

"Unexpected error: .jqm is not defined as a

Having an issue with a jqm function that I need help with. <span class="smaller gray">[ <span class="blueonly"><a href="javascript:void(0)" rel="nofollow" onclick="javascript:jQuery(\'#s ...

Implementing the map function in ReactJS to showcase data on the user interface

I seem to be facing an issue while attempting to utilize an array of data to display a <ul> element. Despite the console.log's working correctly in the code provided below, the list items fail to show up. <ul className="comments"&g ...

Tips for sending data from a JSP to a Servlet with Javascript

My code creates an array of circular buttons with dynamic values. When clicked, these buttons get deleted and their values are stored in a JavaScript object array. I need to send these deleted button values to a servlet once my task is complete. To do this ...

Attempting to download an image through an axios fetch call

There is an issue I am facing while trying to retrieve an image from the website www.thispersondoesnotexit.com. function getImage() { axios({ method: 'get', url: 'https://www.thispersondoesnotexist.com/image' }) ...

"Sliding through pictures with Bootstrap carousel placed beneath the

Currently, I am working on a website that requires a background image, although I personally do not prefer it. The client's preference is to have the navbar transparent so that the background image shows through it. Now, I would like to incorporate a ...

Generate visual representations of data sorted by category using AngularJS components

I am facing an unusual issue with Highcharts and Angularjs 1.6 integration. I have implemented components to display graphs based on the chart type. Below is an example of the JSON data structure: "Widgets":[ { "Id":1, "description":"Tes ...

The term 'MapEditServiceConfig' is being incorrectly utilized as a value in this context, even though it is meant to refer to a type

Why am I receiving an error for MapEditServiceConfig, where it refers to a type? Also, what does MapEditServiceConfig {} represent as an interface, and what is the significance of these brackets? export interface MapEditServiceConfig extends AppCredenti ...

Trigger a Vue method using jQuery when a click event occurs

I'm attempting to attach a click event to an existing DOM element. <div class="logMe" data-log-id="{{ data.log }}"></div> ... <div id="events"></div> Struggling to access external Vue methods within my jQuery click handler. A ...

Swap out The div element with the html() method

I'm encountering an issue when trying to swap out a div element with ajax. My goal is to create a start/stop button functionality. The page displays a list of card elements, each with its own button, which are stored in separate html files. work_orde ...

Documentation for Lambda function within an object

Looking to properly document the sock and data variables using JSDoc in my code. var exec = { /** * @param {Number} sock * @param {String} data */ 1: (sock, data) => { console.log("GG"); }, 2: (sock, data ...

Utilizing Angular JS to Manage Controller Events

I am currently working on an application that requires saving a large amount of data in cascade, similar to a typical master-detail view. Within this view, there is a "Save All" Button which saves each row in an iteration. This process triggers jQuery cus ...

Eliminating symbols such as $, @, and % from a string using jQuery

Need help with removing special characters like $, @, % from a given string. var str = 'The student have 100% of attendance in @school'; Looking for a way to strip % and $ symbols (or any other special characters) from the above string using jQ ...