'Regex for 16 hex char string that contains at least one letter
I want to write regex to recgonize a hex string with length of 16 bytes, for example:
1a2b3c4d1a2b3c4d
The following answers is NOT correct:
[0-9a-fA-F]{16}
because a 16-digit string (e.g., 1234567812345678
) also satisfies this regex. Must EXCLUDE the situation when a 16-byte hex string has no hex letter (a-f
and A-F
) chars.
I found that Go regex does NOT support positive/negtive lookahead, which suppose to solve the problem easily.
How to write such regex in Go?
Solution 1:[1]
You want to match a string that contains 16 hex chars, and one of these hex chars must be alphabetic.
Since the RE2 regex flavor used in Go does not support lookarounds the only way is to list (spell out) all possible variation:
(?i)(?:[A-F][\dA-F]{15}|[\dA-F][A-F][\dA-F]{14}|[\dA-F]{2}[A-F][\dA-F]{13}|[\dA-F]{3}[A-F][\dA-F]{12}|[\dA-F]{4}[A-F][\dA-F]{11}|[\dA-F]{5}[A-F][\dA-F]{10}|[\dA-F]{6}[A-F][\dA-F]{9}|[\dA-F]{7}[A-F][\dA-F]{8}|[\dA-F]{8}[A-F][\dA-F]{7}|[\dA-F]{9}[A-F][\dA-F]{6}|[\dA-F]{10}[A-F][\dA-F]{5}|[\dA-F]{11}[A-F][\dA-F]{4}|[\dA-F]{12}[A-F][\dA-F]{3}|[\dA-F]{13}[A-F][\dA-F]{2}|[\dA-F]{14}[A-F][\dA-F]|[\dA-F]{15}[A-F])
Add ^
at the start and $
at the end to match a whole string matching this pattern, or \b
word boundaries, if you need to match as a whole word in a longer text.
So, this is a whole string matching pattern:
(?i)^(?:[A-F][\dA-F]{15}|[\dA-F][A-F][\dA-F]{14}|[\dA-F]{2}[A-F][\dA-F]{13}|[\dA-F]{3}[A-F][\dA-F]{12}|[\dA-F]{4}[A-F][\dA-F]{11}|[\dA-F]{5}[A-F][\dA-F]{10}|[\dA-F]{6}[A-F][\dA-F]{9}|[\dA-F]{7}[A-F][\dA-F]{8}|[\dA-F]{8}[A-F][\dA-F]{7}|[\dA-F]{9}[A-F][\dA-F]{6}|[\dA-F]{10}[A-F][\dA-F]{5}|[\dA-F]{11}[A-F][\dA-F]{4}|[\dA-F]{12}[A-F][\dA-F]{3}|[\dA-F]{13}[A-F][\dA-F]{2}|[\dA-F]{14}[A-F][\dA-F]|[\dA-F]{15}[A-F])$
This is a whole word matching pattern:
(?i)\b(?:[A-F][\dA-F]{15}|[\dA-F][A-F][\dA-F]{14}|[\dA-F]{2}[A-F][\dA-F]{13}|[\dA-F]{3}[A-F][\dA-F]{12}|[\dA-F]{4}[A-F][\dA-F]{11}|[\dA-F]{5}[A-F][\dA-F]{10}|[\dA-F]{6}[A-F][\dA-F]{9}|[\dA-F]{7}[A-F][\dA-F]{8}|[\dA-F]{8}[A-F][\dA-F]{7}|[\dA-F]{9}[A-F][\dA-F]{6}|[\dA-F]{10}[A-F][\dA-F]{5}|[\dA-F]{11}[A-F][\dA-F]{4}|[\dA-F]{12}[A-F][\dA-F]{3}|[\dA-F]{13}[A-F][\dA-F]{2}|[\dA-F]{14}[A-F][\dA-F]|[\dA-F]{15}[A-F])\b
Here is a convenience JavaScript snippet that will generate this pattern:
function generate() {
var character_count = document.getElementById('char_count').value;
var obligatory_pattern = document.getElementById('obligatory_pattern').value;
var char_pattern = document.getElementById('char_pattern').value;
var pattern = '';
for (var i=0; i<character_count; i++) {
pattern += `${char_pattern}{${i}}${obligatory_pattern}${char_pattern}{${character_count-i-1}}|`;
}
var res = `(?:${pattern.replaceAll('{1}', '').replaceAll(`${char_pattern}{0}`,'').replace(/\|$/,'')})`;
document.getElementById('result').textContent = res.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="one" width=80%"" align="center">
<table>
<tr><td>Character count:</td><td><input type="text" id="char_count" value="16" /></td></tr>
<tr><td>Obligatory pattern:</td><td><input type="text" id="obligatory_pattern" value="[A-F]" /></td></tr>
<tr><td>Character pattern:</td><td><input type="text" id="char_pattern" value="[\dA-F]" /></td></tr>
<tr><td colspan="2"><button onclick="generate()">Generate</button></td></tr>
</table>
</div><br/>
<pre><b><code id="result"/></b></pre>
You need to use it with the (?i)
case insensitive inline modifier, or include a-f
to the ranges.
See the regex demo.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |