1

I have tried the https://www.regex101.com/#javascript tool, as well as a similar stackoverflow question and yet haven't been able to solve/understand this. Hopefully someone here can explain what I am doing wrong. I have created as detailed, step-by-step of an example as I can.

My goal is to be able to parse custom attributes, so for example:

I wrote some jquery code to pull in the attribute and the value, and then wanted to run regex against the result.

Below is the html/js, the output screenshot, and the regular expression screenshot, which says my regex query should match what I am expecting.

Expected result: 'valOne' Result: ':valOne' <-- why am I getting a ':' character?

<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script>
      $(document).ready(function() {
        $('[customAttr]').each(function(){

          var attrValues = $(this).attr('customAttr');

          var regEx_attrVal = /[\w:]+?(?=;|$)/g;
          var regEx_preColon = /[\w]+?(?=:)/g;
          var regEx_postColon = /:(\w*)+?(?=;|\b)/g;

          var customAttrVal = attrValues.match(regEx_attrVal);
          var customAttrVal_string = customAttrVal.toString();
          console.log('customAttrVal:');
          console.log(customAttrVal);
          console.log('customAttrVal_string: '+customAttrVal_string);

          var preColon = customAttrVal_string.match(regEx_preColon);
          preColon_string =preColon.toString();
          console.log('preColon');
          console.log(preColon);
          console.log('preColon_string: '+preColon_string);

          var postColon = customAttrVal_string.match(regEx_postColon);
          postColon_string = postColon.toString();
          console.log('postColon');
          console.log(postColon);
          console.log('postColon_string: '+postColon_string);

          console.log('pre: '+preColon_string);
          console.log('post: '+postColon_string);
        });
      });
    </script>
  </head>
  <body>
      <div customAttr="val1:valOne">
        Test custom attr
      </div>
  </body>
</html>

enter image description here enter image description here

Community
  • 1
  • 1
Ron I
  • 4,090
  • 8
  • 33
  • 64
  • 1
    Instead of posting images, please post link of regex101. Also post some test data, what should be considered as successful match and what not. – Saleem Apr 20 '16 at 23:44
  • The problem is in the javascript code. You should get the group, not do `toString` directly. I forgot the JS code to do it though – Aminah Nuraini Apr 20 '16 at 23:50
  • just split on colons. `var pair="val1:valOne".split(":"); // pair[0]=val1, pair[1]=valOne` – chiliNUT Apr 20 '16 at 23:51

4 Answers4

1

I haven't trudged through all the code, but something you need to understand about regexes is the difference between $0 and $1.

$0 is highlighted in blue. That is the entire part the regex matched.

You want $1. That's where the matches captured by the parenthesis are.

Read more about capture groups here.

var match = myRegexp.exec(myString);
alert(match[1]);  // This accesses $1
Community
  • 1
  • 1
Laurel
  • 5,965
  • 14
  • 31
  • 57
1

When you use String#match() with a regex with a global modifier, all the capture groups (those strings in the regex101.com right-hand bottom 'MATCH INFORMATION' pane are the values captured into Groups with ID 1 and higher) defined in the pattern are lost, and you only get an array of matched values.

You need to remove /g from your regexps and fix them as follows:

var regEx_attrVal = /[\w:]+(?=;|$)/;
var regEx_preColon = /\w+(?=:)/;
var regEx_postColon = /:(\w+)(?=;|\b)/;

Then, when getting the regEx_postColon captured value, use

var postColon = customAttrVal_string.match(regEx_postColon);
var postColon_string = postColon !== null ? postColon[1] : "";

First, check if there is a postColon regex match, then access the captured value with postColon[1].

See the whole updated code:

$(document).ready(function() {
  $('[customAttr]').each(function() {

    var attrValues = $(this).attr('customAttr');

    var regEx_attrVal = /[\w:]+(?=;|$)/;
    var regEx_preColon = /\w+(?=:)/;
    var regEx_postColon = /:(\w+)(?=;|\b)/;

    var customAttrVal = attrValues.match(regEx_attrVal);
    var customAttrVal_string = customAttrVal.toString();
    console.log('customAttrVal:');
    console.log(customAttrVal);
    console.log('customAttrVal_string: ' + customAttrVal_string);

    var preColon = customAttrVal_string.match(regEx_preColon);
    preColon_string = preColon.toString();
    console.log('preColon');
    console.log(preColon);
    console.log('preColon_string: ' + preColon_string);

    var postColon = customAttrVal_string.match(regEx_postColon);
    var postColon_string = postColon !== null ? postColon[1] : "";
    console.log('postColon');
    console.log(postColon);
    console.log('postColon_string: ' + postColon_string);

    console.log('pre: ' + preColon_string);
    console.log('post: ' + postColon_string);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div customAttr="val1:valOne">
  Test custom attr
</div>
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Thanks Wiktor it works great and thanks for breaking it down. In case you/others feel like answering a follow up question, is there a more efficient way to achieve my goal of being able to tag code with custom tags and parsing them? For example, let's say I want to automatically generate documentation on code like this:
    hello world
    . I am looking to get all DOM elements marked by 'documentation' and then parse their tags to generate the docs. I currently am going for the above approach. Any recommendations for a better way?
    – Ron I Apr 21 '16 at 11:35
  • It looks like you need to use JQuery like `$('[documentation]').each(function() { // Process the tag });`. And then just use the DOM properties to get what you need. I am afraid I cannot help more since what you ask is too broad. Check [this demo](https://jsfiddle.net/excLn0hs/). – Wiktor Stribiżew Apr 21 '16 at 12:05
1

use data attributes. you can store json strings in them and access them like objects.

HTML

<div id='div' data-custom='{"val1":"valOne","a":"b"}'></div>

jQ

$("#div").data("custom").val1; //valOne

$("#div").data("custom").a; //b

chiliNUT
  • 18,989
  • 14
  • 66
  • 106
  • Thanks for showing me that possible solution, as I didn't know you could store json strings in data attributes. If you didn't know what any of the keys would be, how could you access them? For example, if you have data-custom peppered throughout your code, each one with different values, how would you iterate through them? The following is not written correctly, but how could I do something like: $('body').data('custom').each(function(index, value) { console.log(index, value) }); – Ron I Apr 21 '16 at 11:19
  • that looks fine to me – chiliNUT May 16 '16 at 02:39
0

I guess this is the regex pattern that you're looking for:

(?!(.*?):).*

Explanation

  • (.*?:) Select all type of values and any number of times and a match that contains (:) simbol
  • (?! :) select inverse values of the first pattern, its kinda negation
  • ( ).* Select all type of values after the evaluations

Also you can do the same with Jquery substring which for me the most simple way to do it, just like this:

How to substring in jquery

Community
  • 1
  • 1