Reputation: 2589
I have a *TEX file contains:
__DATA__
"\left({H^1}, \int {H^2}\right)"
"\left({H^1},\bigoplus{H^2}\right)"
"\left({H^1},{H^2}\right)"
"\left({H^1}, \bigvee {H^2}\right)"
The above *TEX contents I have to check the list of array elements which I have listed below: If any one the elements is matched then retain the line as it is: If no one of the elements matched then I need to replace \left(
into (
and \right)
into )
.
My Arrays:
int frac prod sum oint bigvee bigcup bigcap bigoplus bigotimes
Expected Output:
"\left({H^1}, \int {H^2}\right)"
"\left({H^1},\bigoplus{H^2}\right)"
"({H^1},{H^2})"
"\left({H^1}, \bigvee {H^2}\right)"
What I have tried:
my @mathenv = qw(int frac prod sum oint bigvee bigcup bigcap bigoplus bigotimes);
while(<DATA>) { $mathchk .= $_; }
$boolChk = 'False';
$mathchk=~s#\\left\(((?:(?!\\(?:left|right)).)*)\\right\)# my $fulcnt=$&; my $Content=$1;
foreach my $singlemath(@mathenv)
{
\#print "S: -$singlemath-\n";
if($fulcnt=~m/\\$singlemath/gi)
{ $boolChk = 'True'; }
}
print ": $boolChk \t$fulcnt\n"; system 'pause';
if($boolChk eq 'True') { }
if($boolChk eq 'False') { $fulcnt = "\($Content\)"; }
($fulcnt);
#esg;
#print $mathchk;
__DATA__
"\left({H^1}, \int {H^2}\right)"
"\left({H^1},\bigoplus{H^2}\right)"
"\left({H^1},{H^2}\right)"
"\left({H^1}, \bigvee {H^2}\right)"
I couldn't able to get the correct output hence if someone guide me where I have to modify the above code. Thanks in advance.
Upvotes: 1
Views: 83
Reputation: 66873
For the shown data
use warnings;
use strict;
use List::Util qw(none);
my @terms = qw(int frac prod sum oint bigvee bigcup bigcap bigoplus bigotimes);
my ($paren_L, $paren_R) = map { quotemeta $_ } '\left(', '\right)';
while (my $line = <DATA>)
{
if (none { $line =~ /$_/ } @terms)
{
$line =~ s|$paren_L|(|;
$line =~ s|$paren_R|)|;
}
print $line;
}
__DATA__
"\left({H^1}, \int {H^2}\right)"
"\left({H^1},\bigoplus{H^2}\right)"
"\left({H^1},{H^2}\right)"
"\left({H^1}, \bigvee {H^2}\right)"
with output
"\left({H^1}, \int {H^2}\right)" "\left({H^1},\bigoplus{H^2}\right)" "({H^1},{H^2})" "\left({H^1}, \bigvee {H^2}\right)"
Notes.
This doesn't account for multiple bracketed expressions on a single line
There are (many) other ways to specify parens in Latex (\big(
, \Bigg(
etc).
On the other hand, the shown data is reasonable in a Latex document.
This goes over the line multiple times but is far more flexible than a single regex.
With such simple patterns we need not start the regex engine for each term, but can instead build one pattern with alternations. Substitutions can also be done in one pass, using named capture groups
my $re_terms = '(?:' . join('|', @terms) . ')';
while (my $line = <DATA>)
{
if ($line !~ /$re_terms/)
{
$line =~ s/(?<L>$paren_L)|(?<R>$paren_R)/$+{L} ? '(' : ')'/eg;
}
print $line;
}
which produces the same output.
This does expect data in the shown format: parens always paired, one set on a line.
Upvotes: 1