# Simple way to apply a rule (from list of rules) based on the presence of the a rule key within a string

If I have some strings eg:

str1 = "12-26b-14a";
str2 = "12-21h-14";


and I want to replace the string with a value based on the following rules:

testru = {"12-26b" -> xx, "12-21h" -> yy, "12-42e" -> zz};


I can make the following criteria:

DeleteCases[
ReplaceAll[If[StringMatchQ[str1, # ~~ __], #] & /@
Keys@testru, testru],
Null][[1]]


xx

DeleteCases[
ReplaceAll[If[StringMatchQ[str2, # ~~ __], #] & /@
Keys@testru, testru],
Null][[1]]


yy

This works, but I suspect there are much simpler/ more elegant ways to perform such a seemingly simple task.

In particular, ReplaceAll feels like overkill for a single element!

Any suggestions for an improved method?

## EDIT

I'd rather not mess with the structure of testru since I use this list for other purposes.

Also the strings do not have definite lengths so clipping the string by a certain number of characters is not viable.

• "strings do not have definite lengths" - but if the prefixes are fixed, then Carl's use of StringStartsQ[] for matching suffices. Sep 28, 2018 at 1:46
• @J.M.issomewhatokay., Yes, it would be a good solution (+1 vote). I added the second 'edit' comment to head off other answers based on fixed length strings. Sep 28, 2018 at 1:56
• Into what do you want str1 and str2 to transform? Sep 28, 2018 at 4:29

Maybe something like:

Replace[
{str1, str2},
{_?(StringStartsQ["12-26b"])->xx, _?(StringStartsQ["12-21h"])->yy},
{1}
]


{xx, yy}

If you need to use testru as is, then you could do something like:

Replace[
{str1, str2},
Replace[testru, Rule[a_, b_] :> Rule[PatternTest[Blank[], StringStartsQ[a]], b], {1}],
{1}
]


{xx, yy}

rule = MapAt[_String?(StringStartsQ[#]) &, testru, {All, 1}]

Replace[ {str1, str2}, rule, All]


{xx, yy}

{str1, str2} /. rule


{xx, yy}

Also

srule = # ~~ ___ -> #2 & @@@ testru;

# & @@@ StringReplace[srule] @ {str1, str2}


{xx, yy}