views:

67

answers:

4

Hi there !

I have the following string in php:

$string = 'FEDCBA9876543210';

The string can be have 2 or more (I mean more) hexadecimal characters I wanted to group string by 2 like :

$output_string = 'FE:DC:BA:98:76:54:32:10';

I wanted to use regex for that, I think I saw a way to do like "recursive regex" but I can't remember it.

Any help appreciated :)

A: 

You can make sure there are two or more hex characters doing this:

if (preg_match('!^\d*[A-F]\d*[A-F][\dA-F]*$!i', $string)) {
  ...
}

No need for a recursive regex. By the way, recursive regex is a contradiction in terms. As a regular language (which a regex parses) can't be recursive, by definition.

If you want to also group the characters in pairs with colons in between, ignoring the two hex characters for a second, use:

if (preg_match('!^[\dA-F]{2}(?::[A-F][\dA-F]{2})*$!i', $string)) {
  ...
}

Now if you want to add the condition requiring tow hex characters, use a positive lookahead:

if (preg_match('!^(?=[\d:]*[A-F][\d:]*[A-F])[\dA-F]{2}(?::[A-F][\dA-F]{2})*$!i', $string)) {
  ...
}

To explain how this works, the first thing it does it that it checks (with a positive lookahead ie (?=...) that you have zero or more digits or colons followed by a hex letter followed by zero or more digits or colons and then a letter. This will ensure there will be two hex letters in the expression.

After the positive lookahead is the original expression that makes sure the string is pairs of hex digits.

cletus
+6  A: 

If you don't need to check the content, there is no use for regex.

Try this

$outputString = chunk_split($string, 2, ":");

You might need to remove the last ":".

Or this :

$outputString = implode(":", str_split($string, 2));

Resources :

On the same topic :

Colin Hebert
Please correct the spelling of the function: `chunk_split` and not `chunck_split` .
shamittomar
For removing last `:` use this: `rtrim(chunk_split($string, 2, ":"), ":");`
shamittomar
Thanks :) that did the job :)
Baloo
A: 

Sounds like you want a regex like this:

/([0-9a-f]{2})/${1}:/gi

Which, in PHP is...

<?php
$string = 'FE:DC:BA:98:76:54:32:10';
$pattern = '/([0-9A-F]{2})/gi';
$replacement = '${1}:';
echo preg_replace($pattern, $replacement, $string);
?>

Please note the above code is currently untested.

Ryan Gooler
A: 

Recursive regular expressions are usually not possible. You may use a regular expression recursively on the results of a previous regular expression, but most regular expression grammars will not allow recursivity. This is the main reason why regular expressions are almost always inadequate for parsing stuff like HTML. Anyways, what you need doesn't need any kind of recursivity.

What you want, simply, is to match a group multiple times. This is quite simple:

preg_match_all("/([a-z0-9]{2})+/i", $string, $matches);

This will fill $matches will all occurrences of two hexadecimal digits (in a case-insensitive way). To replace them, use preg_replace:

echo preg_replace("/([a-z0-9]{2})/i", $string, '\1:');

There will probably be one ':' too much at the end, you can strip it with substr:

echo substr(preg_replace("/([a-z0-9]{2})/i", $string, '\1:'), 0, -1);
zneak
http://php.net/manual/en/regexp.reference.recursive.php ;) Please don't use it though!
Daniel Vandersluis
@Daniel Vandersluis: I wish you never showed me that.
zneak
Some regex implementations support recursive "calls/matches" to previously matched groups (Perl, PHP and .NET support this).
Bart Kiers
And what is your definition of a, or the, "regular expression grammar"?
Bart Kiers
@Bart K. The "regular expression grammar" is the language you use when you do regular expressions.
zneak
@zneak, okay, but my point is (was) that there is no single regex grammar: each language uses its own regex-flavor. And when talking about a the "true" regular expressions ("true" as in a mathematical sense), then the groupings of matches is not a part of the grammar. So since you were using matching-groups and were talking about things that were not a part of a grammar, I was just wondering what grammar you were talking about.
Bart Kiers
@Bart K. I honestly thought no regex flavor had recursivity. Though, it seems I'm wrong.
zneak
@zneak, yes, your comment about recursion in regular expression is incorrect but your comment that there would be a "regular expression grammar" also makes little sense to me since every language has its own features (and therefor its own grammar). All in all, I'd either remove this post in its current form, or edit it so that the errors in it are removed. Now it can only accumulate downvotes.
Bart Kiers
@Bart K. I'm fine with accumulating downvotes with this one. If you still don't like the answer after my edits, feel free to edit it or delete it or downvote it.
zneak
@zneak, no, I can't delete other people's answers. But your answer in its current form is better than it was (I removed my down vote).
Bart Kiers