问题
I want to find (if they exist) any hash tags and get the first co-occurrence of each tag plus the text after it but before the next tag if another exists.
*Not all message strings carry a hash tag!
Here is what I am trying to do:
List of possible string examples sent to script:
1) $message = 'Added some new stuff';
2) $message = '#BALANCE balanced movement of X';
3) $message = '#CHANGE some log text #FIX some other log text';
$num = prereg_match_all('@?????@', $message, $matches);
This is the array structure result I am aiming for from the matches:
Result of Example 1)
(
[0] => Array
(
[0] => Added some new stuff
)
)
Result of Example 2)
(
[0] => Array
(
[0] => balanced movement of X
[1] => #BALANCE
)
)
Result of Example 3)
(
[0] => Array
(
[0] => some log text
[1] => #CHANGE
)
[1] => Array
(
[0] => some other log text
[1] => #FIX
)
)
Things driving me nuts trying to find decent documentation on REGEX
回答1:
Try this code:
$msg = '#CHANGE some log text #FIX some other log text';
$msg = preg_replace('/(#[\w]+)(\s+)/', "\n\n$1\n", $msg);
foreach (explode("\n\n", trim($msg)) as $k => $v) {
$res[$k] = array_reverse(explode("\n", $v));
}
print_r($res);
/*
Array
(
[0] => Array
(
[0] => some log text
[1] => #CHANGE
)
[1] => Array
(
[0] => some other log text
[1] => #FIX
)
)
*/
回答2:
Try something like this for all of your test cases:
$messages[] = 'Added some new stuff';
$messages[] = '#BALANCE balanced movement of X';
$messages[] = '#CHANGE some log text #FIX some other log text';
foreach( $messages as $message) {
preg_match_all( '~(#\w+)?\s*([\w\s]+)~i', $message, $matches);
// var_dump( $matches);
echo "Message: " . $message . "\n";
$count = strlen( $matches[1][0]);
if( $count == 0) {
// No hash tags
echo "No hash tags, so the match string text is: " . $matches[2][0] . "\n";
} else {
for( $i = 0; $i < count( $matches[1]); $i++) {
echo "\t Hash tag $i\n";
echo "\t\t - Tag: ".$matches[1][$i]." Value: ".$matches[2][$i]."\n";
}
}
}
This outputs:
Message: Added some new stuff
No hash tags, so the match string text is: Added some new stuff
Message: #BALANCE balanced movement of X
Hash tag 0
- Tag: #BALANCE Value: balanced movement of X
Message: #CHANGE some log text #FIX some other log text
Hash tag 0
- Tag: #CHANGE Value: some log text
Hash tag 1
- Tag: #FIX Value: some other log text
See it work
回答3:
I just got it! After a 3 hour battle, BSDNOOBZ came with the closest answer...
Give it the following cases:
$messages[] = 'Blla vajfkj asfhkha asfha lskahfa';
$messages[] = '#CHANGE reduced sentry health/armor to 325/100 and made them easier to repair with welders #FIX reduced sentry build time to 6 seconds (down from 10)';
foreach($messages AS $message)
{
$num = preg_match_all('@(\#\w+)([^#]+)@', $message, $matches, PREG_SET_ORDER);
if($num > 0)
{
print_r($matches);
} else {
echo $message;
}
}
Results:
string Blla vajfkj asfhkha asfha lskahfa
Array (
[0] => Array
(
[0] => #CHANGE reduced sentry health/armor to 325/100 and made them easier to repair with welders
[1] => #CHANGE
[2] => reduced sentry health/armor to 325/100 and made them easier to repair with welders
)
[1] => Array
(
[0] => #FIX reduced sentry build time to 6 seconds (down from 10)
[1] => #FIX
[2] => reduced sentry build time to 6 seconds (down from 10)
)
)
来源:https://stackoverflow.com/questions/11138191/preg-match-all-after-hash-tag-before-next-hash-tag-in-a-string