Combining two overlapping regular expressions

I have a string containing three consecutive characters at some point. I want to find out if the first two characters match (?:p[tkfcsxlmnr]|t[pkfcsxlmnr]|k[ptfcslmnr]|f[ptkcsxlmnr]|c[ptkflmnr]|s[ptkfxlmnr]|x[ptfslmnr]|b[dgvjzlmnr]|d[bgvjzlmnr]|g[bdvjzlmnr]|v[bdgjzlmnr]|j[bdgvlmnr]|z[bdgvlmnr]|l[ptkfcsxbdgvjzmnr]|m[ptkfcsxbdgvjlnr]|n[ptkfcsxbdgvjzlmr]|r[ptkfcsxbdgvjzlmn]) and the last two characters match (?:[bcfgkmpsvx][lr]|[cs][fkmnpt]|d[jrz]|[jz][bdgmv]|t[crs]). Is there some regular expression syntax for that or do I have to manually write the expression?

I think you need to enumerate the rules in human-speak, combining as many cases as possible (for example, lmnr are always valid for the middle character, while p is valid if the first character was t, i, f, c, s, x, l, m, n, or r). Then use back-references to verify them in your regex.

It is forbidden for both consonants to be the same, as this would violate the rule against double consonants.

It is forbidden for one consonant to be voiced and the other unvoiced. The consonants “l”, “m”, “n”, and “r” are exempt from this restriction. As a result, “bf” is forbidden, and so is “sd”, but both “fl” and “vl”, and both “ls” and “lz”, are permitted.

It is forbidden for both consonants to be drawn from the set “c”, “j”, “s”, “z”.

([ptkfcsx])(^\1) Is two non-identical characters(([ptkfcsx])(?!\1)){2} I think covers half of rules 1 and 2 (the unvoiced half), but I'd have to test it.(([ptkfcsx])(?!\1)){2}|(([bdgvjz])(?!\1)){2} I think would get you halfway there

You don't want {2}. You want to use lookarounds to peek at the second character but not consume it until the second half of the regex, which will be after the bit I was constructing (which will be a bunch of ors in a big paren)

Which gives me this output: (?:bdj|bdr|bdz|bgl|bgr|bjb|bjd|bjg|bjm|bjv|bml|bmr|bvl|bvr|bzb|bzd|bzg|bzm|bzv|cfl|cfr|ckl|ckr|cml|cmr|cpl|cpr|ctc|ctr|cts|dbl|dbr|dgl|dgr|djb|djd|djg|djm|djv|dml|dmr|dvl|dvr|dzb|dzd|dzg|dzm|dzv|fcf|fck|fcl|fcm|fcn|fcp|fcr|fct|fkl|fkr|fml|fmr|fpl|fpr|fsf|fsk|fsl|fsm|fsn|fsp|fsr|fst|ftc|ftr|fts|fxl|fxr|gbl|gbr|gdj|gdr|gdz|gjb|gjd|gjg|gjm|gjv|gml|gmr|gvl|gvr|gzb|gzd|gzg|gzm|gzv|jbl|jbr|jdj|jdr|jdz|jgl|jgr|jml|jmr|jvl|jvr|kcf|kck|kcl|kcm|kcn|kcp|kcr|kct|kfl|kfr|kml|kmr|kpl|kpr|ksf|ksk|ksl|ksm|ksn|ksp|ksr|kst|ktc|ktr|kts|lbl|lbr|lcf|lck|lcl|lcm|lcn|lcp|lcr|lct|ldj|ldr|ldz|lfl|lfr|lgl|lgr|ljb|ljd|ljg|ljm|ljv|lkl|lkr|lml|lmr|lpl|lpr|lsf|lsk|lsl|lsm|lsn|lsp|lsr|lst|ltc|ltr|lts|lvl|lvr|lxl|lxr|lzb|lzd|lzg|lzm|lzv|mbl|mbr|mcf|mck|mcl|mcm|mcn|mcp|mcr|mct|mdj|mdr|mdz|mfl|mfr|mgl|mgr|mjb|mjd|mjg|mjm|mjv|mkl|mkr|mpl|mpr|msf|msk|msl|msm|msn|msp|msr|mst|mtc|mtr|mts|mvl|mvr|mxl|mxr|nbl|nbr|ncf|nck|ncl|ncm|ncn|ncp|ncr|nct|ndj|ndr|ndz|nfl|nfr|ngl|ngr|njb|njd|njg|njm|njv|nkl|nkr|nml|nmr|npl|npr|nsf|nsk|nsl|nsm|nsn|nsp|nsr|nst|ntc|ntr|nts|nvl|nvr|nxl|nxr|nzb|nzd|nzg|nzm|nzv|pcf|pck|pcl|pcm|pcn|pcp|pcr|pct|pfl|pfr|pkl|pkr|pml|pmr|psf|psk|psl|psm|psn|psp|psr|pst|ptc|ptr|pts|pxl|pxr|rbl|rbr|rcf|rck|rcl|rcm|rcn|rcp|rcr|rct|rdj|rdr|rdz|rfl|rfr|rgl|rgr|rjb|rjd|rjg|rjm|rjv|rkl|rkr|rml|rmr|rpl|rpr|rsf|rsk|rsl|rsm|rsn|rsp|rsr|rst|rtc|rtr|rts|rvl|rvr|rxl|rxr|rzb|rzd|rzg|rzm|rzv|sfl|sfr|skl|skr|sml|smr|spl|spr|stc|str|sts|sxl|sxr|tcf|tck|tcl|tcm|tcn|tcp|tcr|tct|tfl|tfr|tkl|tkr|tml|tmr|tpl|tpr|tsf|tsk|tsl|tsm|tsn|tsp|tsr|tst|txl|txr|vbl|vbr|vdj|vdr|vdz|vgl|vgr|vjb|vjd|vjg|vjm|vjv|vml|vmr|vzb|vzd|vzg|vzm|vzv|xfl|xfr|xml|xmr|xpl|xpr|xsf|xsk|xsl|xsm|xsn|xsp|xsr|xst|xtc|xtr|xts|zbl|zbr|zdj|zdr|zdz|zgl|zgr|zml|zmr|zvl|zvr)

1. It is forbidden for both consonants to be the same, as this would violate the rule against double consonants.

It is forbidden for one consonant to be voiced and the other unvoiced. The consonants “l”, “m”, “n”, and “r” are exempt from this restriction. As a result, “bf” is forbidden, and so is “sd”, but both “fl” and “vl”, and both “ls” and “lz”, are permitted.

It is forbidden for both consonants to be drawn from the set “c”, “j”, “s”, “z”.