0

I'm replacing text with font icons. An look up table would look like:-

 var sym = {'(a)': (apple icon in utf-8),
            '(A)': (angel icon),
            ...
            '(g)': (...),
            '(G)': (last icon) } anything after G is ignored.

Now (a)iPhone when translated to upper case should be (a)IPHONE, leaving the (a) untouched since uppercase (A) is a different icon altogether. Anything that doesn't match like (r)iPhone or (tm)iPhone would be converted.

Question: Is there an algorithm that avoids character by character checking, perhaps using native regex functions? Enclosed is the Javascript coding:

'(a) (az)text'.replace(/\(\w+\)/g, function (matches) { 
          return matches } )
    .replace(/.*(?!\(\w+\)).*/g, function (matches) { // needs fixing
          return matches.toUpperCase() } 
 ) // returns "(A) (AZ)text"
0

2 Answers 2

0

This can be done by constructing the regex as done in this answer and supply a replacement function to conditionally replace the string:

// ES5
'(a) (az)text'.replace(/(\(\w+\))|(?:(?!\(\w+\)).)*/g, function ($0, $1) {
      return $1 == null ? $0.toUpperCase() : $1
});

// ES6
'(a) (az)text'.replace(/(\(\w+\))|(?:(?!\(\w+\)).)*/g,
                       ($0, $1) => $1 == null ? $0.toUpperCase() : $1);

The regex consists of an alternative of two sub-expressions:

  • The initial regex, describing the text you don't want to replace \(\w+\).
  • The "inverse" regex, describing the text you want to replace, constructed by using the check-and-repeat-for-each-character pattern: (?:(?!\(\w+\)).)*.

The second alternative can't stand-alone, since it can match a) in (a) due to the bump-along on failure behavior of regex search function. We need the initial regex to consume and do the bump-along for us.

A capturing group is needed on either branch (in this case, we go with the first branch), so that you can check which alternative the match belongs to.


On the same question, I have an alternate solution which doesn't require the need to change the regex, implemented with RegExp.exec.

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent answer, and for my case, the return line is replaced with return $1 == null ? $0.toUpperCase() : (sym[$1] || $1.toUpperCase()). Good explanation on "2nd alternative can't stand-alone".
0

I'm not sure how exactly you're planning to use this and whether or not you need some sort of complex parser, but here's a solution that might help you find your way: http://jsbin.com/jabuloqaba/edit?html,js,output

If you're expecting it to extract these icons/labels from a large body of text, it seems to me that you'd need some way to delimit the end of the label for capitalization purposes, so at that point you might as well just wrap the whole segment in some element.

This script works well enough for that scenario.

Basically all of the icon generation is in the iconizer object that is returned from the IIFE (the big wrapping function blob at the top). That IIFE returns an object with two exposed properties, one of which is a method and the other is another object. The method is iconize and that's your main way to interact with the object, but you will also want to use iconMap to set the map that you had in your question.

After that, all that's left is selecting the elements you want to run the iconizer on and let it do its work.

It seems like maybe you might have mostly needed help with the regex, so let me expound upon that a bit:

Let's split the expression apart:

/   (.*)   \(   (\S+)   \)   (.*)   /
    before      icon         after

The ( and ) make sure that the regex is looking for the literal parenthesis characters. The parenthesis without the escaping backslash are the capture groups, and you can see that they are mapped to icon, before, and after in the splitIcon method.

From there we can do our lookup and everything is pretty rosy. Let me know if you have any questions!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.