PvDev
PvDev

Reputation: 829

How to check a string matches a regex in JS?

$('.btn-sets').on('click', function() {
    var $this = $(this);
  $this.button('loading');
  function getMatches(string, regex, index) {
    index || (index = 1); // default to the first capturing group
    var matches = [];
    var match;
    while (match = regex.exec(string)) {
      matches.push(match[index]);
    }
    return matches;
    }


    // Example :
    var myString = ".data-label-validation";
    var myRegEx = "(start|stop)-(ed|f|m|s|su|t|th|w|wd)-([1-9]|1[0-2])_([0-5][0-9])(?i)(am|pm)-(cst|est|mst|pst)";

    // Get an array containing the first capturing group for every match
    var matches = getMatches(myString, myRegEx, 1);

    // Log results
    document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
    console.log(matches);
    setTimeout(function() {
       $this.button('reset');
   }, 8000);
    <div class="btn-group btn-group-sm" role="group" >
      <button id="startHour" type="button" class="btn btn-secondary" data-toggle="dropdown" href="#">
        hour
      </button>
        <div class="dropdown-menu" aria-labelledby="startHour">
          <a class="dropdown-item" href="#">1</a>
          <a class="dropdown-item" href="#">2</a>
          <a class="dropdown-item" href="#">3</a>
          <a class="dropdown-item" href="#">4</a>
          <a class="dropdown-item" href="#">5</a>
          <a class="dropdown-item" href="#">6</a>
          <a class="dropdown-item" href="#">7</a>
          <a class="dropdown-item" href="#">8</a>
          <a class="dropdown-item" href="#">9</a>
          <a class="dropdown-item" href="#">10</a>
          <a class="dropdown-item" href="#">11</a>
          <a class="dropdown-item" href="#">12</a>
        </div>
        <span style="color:white; background-color:#5A6268">:</span>
  <div class="btn-group btn-group-sm" role="group">
        <button id="startMinute" type="button" class="btn btn-secondary" data-toggle="dropdown" href="#">min</button>
        <div class="dropdown-menu" aria-labelledby="startMinute">
          <a class="dropdown-item" href="#">00</a>
          <a class="dropdown-item" href="#">05</a>
          <a class="dropdown-item" href="#">10</a>
          <a class="dropdown-item" href="#">15</a>
          <a class="dropdown-item" href="#">20</a>
          <a class="dropdown-item" href="#">25</a>
          <a class="dropdown-item" href="#">30</a>
          <a class="dropdown-item" href="#">35</a>
          <a class="dropdown-item" href="#">40</a>
          <a class="dropdown-item" href="#">45</a>
          <a class="dropdown-item" href="#">50</a>
          <a class="dropdown-item" href="#">55</a>
        </div>
    </div>
  <div class="btn-group btn-group-sm" role="group">
      <button type="button" class="btn btn-secondary btn-toggle-time" data-toggle="collapse"href= "#">am</button>
  </div>
  <div id="zone" class="btn-group btn-group-sm" role="group">
      <button type="button" class="btn btn-secondary" data-toggle="dropdown">zone</button>
      <div class="dropdown-menu" aria-labelledby="zone">
        <a class="dropdown-item" href="#" data-tz-abbrev="est">America/New_York</a>
        <a class="dropdown-item" href="#" data-tz-abbrev="cst">America/Chicago</a>
        <a class="dropdown-item" href="#" data-tz-abbrev="mst">America/Devner</a>
        <a class="dropdown-item" href="#" data-tz-abbrev="pst">America/Los_Angeles</a>
      </div>
  </div>
  <div class="btn-group btn-group-sm" role="group">
      <button data-name="{{.Name}}" data-zone="{{.Zone | baseUrl}}" data-set-action="start" type="button" class="btn btn-primary btn-sets" id="load" data-loading-text="<i class='fa fa-spinner fa-spin'></i> Processing">Set</button>

    </div>
</div>

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
  {{range .Projects}}

  <div id={{.ProjectID}} class="d-none justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom right-content">

    <h1 class="h2">Project:{{.Name}}</h1>
  <div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
  <div class="btn-group mr-2" role="group" aria-label="First group">
    <button type="button" class="btn btn-secondary">Compute API Enabled</button>
  </div>
  <div class="btn-group mr-2" role="group" aria-label="Second group">
    <button type="button" class="btn btn-secondary">Service Account Key</button>
  </div>
  <div class="btn-group" role="group" aria-label="Third group">
    <button type="button" class="btn btn-secondary">Other Errors</button>
  </div>
</div>
<hr>


<div class="container">


<tbody data-label-validation="{{labelValidation}}">
{{range .Instances}}
<tr>
<td >{{.Name}}</th>
<td>{{.Type | baseUrl}}</td>
<td>{{.Zone | baseUrl}}</td>
<td>
  {{template "startup.html" .}}
</td>
<td>
  {{template "startup.html" .}}
</td>
<td>

</td>
<td>
  <h6>$0.00</h6>
</td>

{{end}}
</tbody>

</div>

</div>
{{end}}
</main>

I have kept two buttons namely set-1 and set-2. When click on set-2 it should check string for validation, if string matches then it should say data matches successfully else match not found.

Button for set button:

<div class="btn-group btn-group-sm" role="group">
 <button data-name="{{.Name}}" data-zone="{{.Zone | baseUrl}}" data-set- 
  action="start" type="button" class="btn btn-primary btn-sets" id="load" 
   data- 
  loading-text="<i class='fa fa-spinner fa-spin'></i> Processing">Set</button>
 </div>

Javascript code which i have tried for validation:

  <script>
  $('.btn-sets').on('click', function() {
  var $this = $(this);
  $this.button('loading');
  function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
  matches.push(match[index]);
  }
  return matches;
  }


   // Example :
   var myString = ".data-label-validation";
    var myRegEx = "(start|stop)-(ed|f|m|s|su|t|th|w|wd)-([1-9]|1[0-2])_([0-5] 
   [0-9])(?i)(am|pm)-(cst|est|mst|pst)";

    // Get an array containing the first capturing group for every match
     var matches = getMatches(myString, myRegEx, 1);

    // Log results
   document.write(matches.length + ' matches found: ' + 
   JSON.stringify(matches))
   console.log(matches);
   setTimeout(function() {
   $this.button('reset');
   }, 8000);
   });

 </script>

Data-validation for string from label code:

 <tbody data-label-validation="{{labelValidation}}">
 {{range .Instances}}
 <tr>
 <td >{{.Name}}</th>
 <td>{{.Type | baseUrl}}</td>
 <td>{{.Zone | baseUrl}}</td>
  <td>
  {{template "startup.html" .}}
 </td>
  <td>
  {{template "startup.html" .}}
  </td>
  <td>
    <button type="button" class="btn {{.Status | statusButtonClass}} btn- 
   circle" 
    data-toggle="popover" data-placement="right" data-content="{{.Status}}" 
   data- 
   trigger="hover">      
    <!-- <i class="glyphicon glyphicon-ok"></i> -->
    </button>
</td>
 <td>
 <h6>$0.00</h6>
</td>
</tr>
{{end}}
</tbody>

Any help much appreciated!!!

Upvotes: 1

Views: 1300

Answers (2)

Sergio Nikolaev
Sergio Nikolaev

Reputation: 789

A lot of errors in your code. First, your regex string is not valid js regex string. This is no-go for js: "(?i)" You should mimic lookbehind assertions in js or send string to back-end to validate. And don't split strings on multiple lines, just keep it one line.

Then, you tried to get data from element by passing it's className to your function. This is a no-go too. First get element, then extract the data. Like this:
var testString = $('#table').attr('data-table');

Then, what are you trying to do here? this.button('loading'); There is no such method in JS. I guess you tried to add a loading state to a button. You could do it like this: this.text('loading');

Then, you did not made regexp object right. Use constructor, like this: regex = new RegExp(regex);

Just keep it simple:

var testRegexString = '/(start|stop)-(ed|f|m|s|su|t|th|w|wd)-([1-9]|1[0-2])_([0-5] [0-9])(am|pm)-(cst|est|mst|pst)/ig';

var testString = $('#table').attr('data-table');

function validateString(string, regex) {
  regex = new RegExp(regex);
  var matchesArray = regex.exec(string);
  var matchesCount = matchesArray.length - 1;
  return matchesArray ? matchesCount + ' Matches found' : 'No matches found';
}

$('#btn1').on('click', function(){
  $(this).text('loading');
  var validationResult = validateString(testString, testRegexString);
  $('#message').text(validationResult);
  $(this).text('Validate Again!');
});

And working snippet here jsfiddle

Upvotes: 1

Boris
Boris

Reputation: 1191

In js a regex can be typed as a litteral with /pattern/flags (see the doc, and https://regexr.com/ for a lot of help with js regexes).

Then, when you exec() your regex, it gives you a simple array with the matches and capture groups.

Here is a version of what I think you were trying to accomplish. I removed a lot of fluff from your snippet in order to get to the heart of the question : regex matching. I also created some strings matching (and not matching) your regex.

function getMatches(string, regex, index) {
  if(index === undefined)
    index = 1;
    var matches = [], match;
  while( (match = regex.exec(string)) !== null)
    if(match.length > index)
      matches.push(match[index]);
  return matches
 }


// Example :
    var myStrings = [ // array of strings to test
      "stop-su-5_25pm-cst",
      "nomatch-PLEASE",
      "start-f-1_05am-mst",
      "start-ed-10_53pm-pst",
      "start-th-3_03am-pst",
    ];
    //this is a case-insensitive, global regex. Please note that you need to put the g here in oder to be able to loop through matches.
    var myRegEx = /(start|stop)-(ed|f|m|s|su|t|th|w|wd)-([1-9]|1[0-2])_([0-5][0-9])(am|pm)-(cst|est|mst|pst)/ig;

    // log the result of the function for each string
for(let string of myStrings){
    var matches = getMatches(string, myRegEx, 1);
    console.log(string, ":", matches);
}

hope that helps.

Upvotes: 1

Related Questions