根据数组中的一个前缀将字符串分为两部分

根据数组中的一个前缀将字符串分为两部分

问题描述:

So I have medical licenses that are kept as a string in the db. I need a way to show a license letter(s) (prefix) and number separately.

The array of prefixes is pre-defined:

$license_letters = array('20A', 'A', 'C', 'CNM', 'G', 'NP', 'PA');

And licenses look like 20A345000, C11006, G678999, PA200200, and so on. So I need to be able to get '20A' and '345000' or 'C' and '11006' for any license.

Searching by the first digit will not work because one of the possible prefixes is 20A. I'm pretty sure there must be a simple solution, but I can't think of it. Would appretiate any help.

所以我的医疗许可证在数据库中保存为字符串。 我需要一种方法来显示 许可证字母(前缀)和数字分开。 p>

前缀数组是预定义的: p>

  $ license_letters = array  ('20A','A','C','CNM','G','NP','PA'); 
  code>  pre> 
 
 

许可证看起来 如20A345000,C11006,G678999,PA200200等等。 我需要能够获得'20A'和'345000'或'C'和'11006'作为任何许可证。 p> 按第一个数字搜索将不起作用,因为其中一个可能的前缀是20A。 我很确定必须有一个简单的解决方案,但我想不到它。 应该提供任何帮助。 p > div>

If it is true that no license string is a part of any other (you don't have both "A" and "AB" in the list), then just loop through and find the first match as follows:

function parts($licenseString) {
    $foreach($license_letters AS $prefix) {
        if(strpos($licenseString, $prefix) === 0) {
            return [$prefix, substr($licenseString, strlen($prefix)];
        }
    }
}

Edit: I meant to use === in the compare. strpos returns 'false' when no match is found, we want a match at position zero, hence we are looking for a return value which is specifically 0 (type number). Thanks for commenters pointing this out.

You may want to sort the array of prefixes by the length of the string values inside of them to avoid cases with multi-character prefixes (for example '20A') could get confused with single character prefixes (for example 'A'):

/**
 * Compare two string values
 *
 * @param $value1 string 1st value to compare
 * @param $value2 string 2nd value to compare
 *
 * @return bool true if the second string is longer than the first
 */
function compareStringLength($value1, $value2)
{
    return (strlen($value1) < strlen($value2));
}

/**
 * Parse a license string
 *
 * @param     $license         string
 * @param     $licensePrefixes array of license prefixes
 *
 * @return array [prefix,license without prefix]
 */
function parseLicense($license, $licensePrefixes)
{
    //The limit to number of times the license prefix will be replaced
    $limit = 1;
    foreach ($licensePrefixes AS $prefix) {
        if (strpos($license, $prefix) !== false) {
            $license = str_replace($prefix, "", $license, $limit);

            return array($prefix, $license);
        }
    }
}

$licensePrefixesArray = array('20A', 'A', 'C', 'CNM', 'G', 'NP', 'PA');

/*
Sort the array to prevent confusion with multi-character prefixes (for example '20A')
and single character prefixes (for example 'A')
*/
usort($licensePrefixesArray, "compareStringLength");

print_r(parseLicense("20A345000", $licensePrefixesArray));
print_r(parseLicense("PA200200", $licensePrefixesArray));
print_r(parseLicense("A2533226", $licensePrefixesArray));