image thumbnail
from strpat: a pedestrian, exactly matching pattern finder / replacer by us
STRPAT finds and replaces an exactly matching pattern in a character or numeric string

[nvec,sout]=strpat(str,pat,npat)
%STRPAT		EXACT pattern search and replacement
%
%		STRPAT searches for EXACTLY matching patterns
%		in a character or numeric string and replaces
%		the occurrences with another pattern.
%
%		see also findstr, strfind, strrep, regexp, regexprep
%
%SYNTAX
%-------------------------------------------------------------------------------
%		 S       = STRPAT(VEC,PAT)
%				to find indices of PAT in VEC
%
%		[NVEC,S] = STRPAT(VEC,PAT,REP)
%				to replace PAT with REP
%
%INPUT
%-------------------------------------------------------------------------------
% VEC	:	a STRING or NUMERIC array
% PAT	:	a pattern of the same type as VEC including NaNs
% REP	:	a pattern of the same type as VEC
%
% OUTPUT
%-------------------------------------------------------------------------------
% NVEC	:	VEC with PATs replaced by REPs
% S	:	output struc with (selected) fields
%		  .n:	nr of occurrences of PAT
%		.iob:	start     indices of PAT
%		.ioe:	end       indices of PAT
%		.irb:	start     indices of REP
%		.ire:	end       indices of REP
%
%
% EXAMPLES
%-------------------------------------------------------------------------------
%		strrep('aa_a_aaa_aa','a','XXX')		% <- STRREP
% %			XXXXXX_XXX_XXXXXXXXX_XXXXXX
%		strpat('aa_a_aaa_aa','a','XXX')		% <- STRPAT
% %			aa_XXX_aaa_aa
%		strpat('aa_a_aaa_aa','aa','X') 
% %			X_a_aaa_X
%		strpat('aa_a_aaa_aa','a','XXX')
% %			aa_XXX_aaa_aa
%		strpat([1:3,pi,5:7],pi,nan)
% %			1 2 3 NaN 5 6 7
%		strpat(pi*(1:6),pi*(4:5),[])
% %			3.1416 6.2832 9.4248 18.85
%		strpat(pi*(1:6),pi*(4:5),[nan inf -inf nan])
% %			3.1416 6.2832 9.4248 NaN Inf -Inf NaN 18.85
%		strpat(pi*(1:6),pi*(4:5),1:3)
% %			3.1416 6.2832 9.4248 1 2 3 18.85
%		strpat([-10,nan,1,-10,nan,nan,1,nan,1,-10],[nan,1],inf)
% %			-10 Inf -10 NaN Inf Inf -10

% created:
%	us	20-Mar-2002
% modified:
%	us	21-Mar-2002		/ CSSM
%	us	15-Feb-2003		/ CSSM (R13)
%	us	05-Jul-2006		/ FEX  (R14.SP3)
%	us	22-Apr-2010 09:57:37	/ FEX  (R2010a)
%
% localid:	us@USZ|ws-nos-36362|x86|Windows XP|7.10.0.499.R2010a

%--------------------------------------------------------------------------------
function	[nvec,sout]=strpat(str,pat,npat)

	if	nargin < 2
		help strpat;
		return;
	end

		snan='';
		hasnan=0;

	if	isnumeric(pat)
		snan=cast(nan,class(pat));
		onan=snan;
		opat=pat;

		in=isnan(pat);
	if	any(in)
		hasnan=1;
		snan=cast(sum(rand(1,5)),class(pat));
	while	any(pat==snan)				||...
		any(str==snan)
		hasnan=hasnan+1;
		snan=cast(sum(rand(1,5)),class(pat));
	end
		pat(in)=snan;
		str(isnan(str))=snan;
	end
	end

		sout.pat=pat;
		sout.npat=[];
		sout.hasnan=hasnan;
		sout.snan=snan;
		sout.n=0;
		sout.iob=[];
		sout.ioe=[];
		sout.irb=[];
		sout.ire=[];

		[nr,nc]=size(str);
	if	nr > 1		&&...
		nc > 1
		sout.dim=size(str);
		disp('strpat> input must be a vector');
	if	nargout
		nvec=sout;
	end
		return;
	end
		str=str(:)';
		pat=pat(:)';
		nvec=str;
		sout.iob=[];
		sout.ioe=[];
		z=strfind(str,pat);
	if	~isempty(z)
		zd=(diff(z)-1)~=0;
		ld=[1 zd] & [zd 1];
	if	any(ld)
		sout.iob=z(ld);
		sout.ioe=sout.iob+numel(pat)-1;
		[sout.iob,sout.iob,sout.ioe]=STRPAT_prune(sout.iob,sout.ioe,false);
		sout.n=numel(sout.iob);
	end
	end

	if	sout.hasnan
		sout.pat=opat;
		sout.snan=onan;
	end

	if	~sout.n
	if	sout.hasnan
		nvec(nvec==snan)=onan;
	end
		disp('strpat> EXACT pattern not found');
		return;
	end

	switch	nargin
	case	2
		nvec=sout;
		return;
	otherwise
		sout.npat=npat;
		[nvec,sout]=STRPAT_repstr(str,pat,npat,sout);

	if	sout.hasnan
		nvec(nvec==snan)=onan;
	end
	end

end
%--------------------------------------------------------------------------------
function	[nvec,sout]=STRPAT_repstr(str,pat,npat,sout)

% ENGINE	01-Dec-2005
% -------------------------
		pp=~STRPAT_fmep(str,sout.iob,sout.ioe);
	if	~numel(npat)
	if	any(pp)
		nvec=str(pp);
	else
		nvec=[];
	end
	else
		dlen=numel(npat)-numel(pat);
		nlen=numel(str)+numel(sout.iob)*(numel(npat)-numel(pat));
		nvec=cast(zeros(1,nlen),class(str));
		sout.irb=sout.iob+dlen*(0:sout.n-1);
		sout.ire=sout.irb+numel(npat)-1;
		gg=STRPAT_fmep(nvec,sout.irb,sout.ire);
		nvec(~gg)=str(pp);
		nvec(gg)=STRPAT_repmat(npat,sout.n);
	end
end
%--------------------------------------------------------------------------------
%--------------------------------------------------------------------------------
% UTILITIES
% 	- FMEP		fast MEP
%				generates logical epochs based on indices
%				ixbeg(1:end):ixend(1:end)
%	- FREPMAT	fast REPMAT
%--------------------------------------------------------------------------------
%--------------------------------------------------------------------------------

% created:
%	us	02-Oct-2002		/	MEP
% modified:
%	us	03-Oct-2002		/	MEP	FEX
%	us	05-Jul-2006		/	FMEP	strpat

%--------------------------------------------------------------------------------
function	vix=STRPAT_fmep(v,ixb,ixe)

% prune input ...
		ixs=STRPAT_prune(ixb,ixe,true);

% ... and create logical array
		vix=STRPAT_mepoch(v,ixs);
end
%--------------------------------------------------------------------------------
% prune input list to remove adjacent blocks
function	[ixs,ixb,ixe]=STRPAT_prune(ixb,ixe,oflg)

% + overlap
	if	oflg
		ixs=ixb(2:end)-1>ixe(1:end-1);
		ixs=[ixb([true,ixs]);ixe([ixs,true])];
		ixs=ixs(:).';

% - overlap
	else
		rx=[false,ixb(2:end)<=ixe(1:end-1)];
	if	any(rx)
		rx=find(rx);
		rx=[rx-1,rx];
		ixb(rx)=[];
		ixe(rx)=[];
	end
		ixs=[ixb;ixe];
		ixs=ixs(:).';
	end
end
%--------------------------------------------------------------------------------
function	vix=STRPAT_mepoch(v,ixs)

		vlen=numel(v);
		tix=zeros(1,vlen+1);
		tix(ixs(2:2:end)+1)=-1;
		tix(ixs(1:2:end-1))=1;
		vix=cumsum(tix);
		vix=vix~=0;
		vix(vlen+1:end)=[];
end
%--------------------------------------------------------------------------------
% fast REPMAT
function	r=STRPAT_repmat(r,nrep)

		ix=(1:numel(r)).';
		r=r(:,ix(:,ones(1,nrep)));
end
%--------------------------------------------------------------------------------

Contact us