Your data is delineated by "|"? How about:
($clliA,$clliB) = (split "|",$source,16)[14,15];
This splits $source into fields that were separated by |, but only the first 16 of them, and puts them into a list, of which you the 15th and 16th elemensts thereof.
Update I guess everyone thought of split...and are faster typers!
Your use of .* is particularly inefficient. Going with a simpler 3-field case: /^.*A.*A.*$/, it would match "shAzAm" by:
match "shAzAm" with .*, can't find A, backtrack.
match "shAzA" with .*, can't find A, backtrack.
match "shAz" with .*
match "shAzA" with .*A
match "shAzAm" with .*A.*, can't find A, backtrack
match "shAzA" with .*A.*, can't find A, backtrack
match "shA" with .*, can't find A, backtrack
match "sh" with .*
match "shA" with .*A
match "shAzAm" with .*A.*, can't find A, backtrack,
and so forth. Imagine that with 16 .*A combinations, like you had.