Viaches
Viaches

Reputation: 401

Regex expression for "hotkey string"

We need to find expression for search "hotkey" in string with Javascript. That option, which is almost finds everything except sequences: Ctrl + M, K, o, i. As he finds ... that absolutely we do not need :)

EDIT:

(?=((ctrl|alt|shift|,|\.|\/)+?\s*[+\-/]\s*(((numpad\s*[\w/\*\-\+\.]+)|(ctrl|alt|shift|,|\.|\/|[a-z]+)+?,?)\s*(?=((([a-z],)\s*[a-z])\s*,?\s*)?)\1(?=([a-z])?)\1)))\1

test multistring variant, case insensitive

<p>Ctrl + Insert, K</p>
<ul>Ctrl +,</ul>'
list Ctrl + , of end
colomn Ctrl + .</>'
<q>Ctrl + M</q>'
<a>Ctrl + M, K, o, i</a>
row Ctrl + M, , + P. While...
<rom>Ctrl + M, K, p</rom>'
<tag>Ctrl + M, Shift + O</tag>'
press Ctrl + M, Shift + O, , + P! Thanks.
Stop. Ctrl + M, Shift + O, / + P</end>
<anytag>Ctrl + Numpad +/-</anytag>'

Where am I wrong?

*Sorry, I can not insert preview due to insufficient reputation

Upvotes: 0

Views: 1508

Answers (1)

Sunny Pun
Sunny Pun

Reputation: 726

In the group (ctrl|alt|shift|,|\.|\/)+? it captures a . In the character class you haven't escaped the -, so [+-/] indeed acts as "characters between ascii value of +(43) and /(47), which namely are +,-./. In the last group before the |, you also allowed it to capture a third .. Thus ... can be captured, you may avoid this by escaping the - with [+\-/].

Here is a version that I guess may work for you:

(ctrl|shift|alt)\s*\+\s*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert)(\s*(,|\+)\s*((ctrl|shift|alt)\s*\+\s*)*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert))*(?=\W)

I am using https://regex101.com/ to see matches in realtime.

  1. I start with thinking that it should capture units (a-z,.+-/) so I now have [a-z+\-.,/] (to avoid confusion I didn't use [+-/] directly.
  2. And then, we shouldn't capture C,t,r,l or any word as separated matches. So I added a positive lookbehind: [a-z+\-.,/](?=\W)
  3. It should start with a modifier key (Ctrl, Alt, Shift) as a sequence - otherwise it may capture normal English words like I: (ctrl|shift|alt)\s*\+\s*[a-z+\-.,/](?=\W)
  4. Suddenly, oh Numpad with 0-9+-/ should be also units, let's make the character class in step 1 a group, for capturing units: (ctrl|shift|alt)\s*\+\s*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+)(?=\W)
  5. And I also add Insert as one of the capturable units: (ctrl|shift|alt)\s*\+\s*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert)(?=\W)
  6. Finally, let's add the repeating group which captures ,(units) occurring after the first captured Hotkeys (Modifier + unit): (ctrl|shift|alt)\s*\+\s*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert)()*(?=\W). Yup, adding a blank ()* to ensure the regex is still balanced and working for old matches.
  7. We put group 2 into the empty bracket so it works as we thought: , with units: (ctrl|shift|alt)\s*\+\s*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert)(\s*,\s*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert))*(?=\W)
  8. The only one we cannot capture is , + P and / + P, because we haven't captured unit + unit groups! And we may have it repeated a number of times... The easiest and laziest way - making the + also as a separator (same level as ,): (ctrl|shift|alt)\s*\+\s*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert)(\s*(,|\+)\s*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert))*(?=\W)
  9. Understanding the above, we want Ctrl + M, Shift + O, / + P to be captured - that means, we should also add optional modifiers in front of the units: (ctrl|shift|alt)\s*\+\s*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert)(\s*(,|\+)\s*((ctrl|shift|alt)\s*\+\s*)*([a-z+\-.,/]|Numpad\s*[0-9+\-/]+|insert))*(?=\W)

Upvotes: 2

Related Questions