Regex that matches a string, but only if the other string is missing on one line

I use many different Regex implementations as it happens on multiple systems (Linux, Windows, VS, notepad ++, etc.); it's just where I have a client who wants to remove auto-sizing. The goal is to use a regex where ever the tool found any string with a width but no autoselect width, then add autowidth. I'm just asking how to find it, but I intend to use what I find here in the replacement line for my editor. I have a bit down replacement: I just didn't figure out how to get one with the other when the other is far away from it.

Using https://regex101.com/ I've tried literally dozens of search strings.

This was my starting point for the search string and several attempts to get feedback to rule out AutoWidth anywhere in the line. Lines 2 and 3 are basically the same thing, but I didn't know what else to try. I am guessing that anything that works for lookbehind will work for look, but as you can see, I cannot even work behind.

(?<! AutoWidth="false") width="\d*"(?! AutoWidth="false")
(?<! AutoWidth="false").*? width="\d*"(?! AutoWidth="false")
(?<! AutoWidth="false")[0-9a-zA-Z" =]*? width="\d*"(?! AutoWidth="false")

      

I am stuck, the distance between AutoWidth and Width is eluding me.

These are my goals

1->  <column name="Selected" AutoWidth="false" IsEditable="true" datatype="bool" width="20"/>
2->  <column width="40" AutoWidth="false" name="ExternalIdOrEmpty" index="XIDname" sort="true"/>
3->  <column width="40" name="Tax Rate" index="TRname" sort="true" AutoWidth="false"/>
4->  <column width="40" name="Total Tax" index="TTname" sort="true"/>
5->  <column name="Tax Deductible" index="TDname" sort="true"/>

      

I want to find all lines containing

width = "\ d *"

but not containing

Autowidth = "\ d *"

anywhere on the same line.

This means that only line 4 in the above samples will meet my criteria.

UPDATE:

I am willing to use any other tool that will get the job done. So XSLT etc. Everything is good. The only requirement is that this tool is usually available on Windows, Linux and Mac, and is also open source or free and well known.

The complete xml is huge. The editing function here is limited to 30.00 characters, but a good example here.

<?xml version="1.0" encoding="utf-8" ?>
<spread>
  <ViewPatientOutboundReferralFilter>
    <FindColumn name="ViewUid" index="guid" visible="false" />
    <FindColumn name="Selected" caption=" " visible="true" IsEditable="true" datatype="bool"/>
    <FindColumn name="PatientName" caption="Patient Name" visible="true" width="150" hyperlink="true" AutoWidth="false"/>
    <FindColumn name="ReferToProviderName" caption="Provider" visible="true" AutoWidth="false" width="150" hyperlink="true"/>
    <FindColumn name="ReferredToMedicalServicesProviderName" caption="Medical Services Provider" visible="true" width="150" hyperlink="true"/>
    <FindColumn name="ProviderRole" caption="Provider Role" visible="true" width="80" hyperlink="true"/>
    <FindColumn name="StatusName" caption="Current Status" visible="true" width="100" hyperlink="true"/>
    <FindColumn name="ServiceSiteName" caption="Service Site" visible="true"/>
    <FindColumn name="VisitDate" caption="Visit Date" visible="true" width="90" datatype="date"/>
    <FindColumn name="AppointmentDate" caption="Appointment Date" visible="true" datatype="datetime" width="90"/>
    <FindColumn name="Notes" caption="Comments" visible="true" width="120"/>
    <FindColumn name="AppointmentNotes" caption="Referral Notes" visible="true" width="120"/>
    <FindColumn name="DisplayName" visible="false" index="name"  />
    <FindColumn name="ProviderUid" visible="false" storeproperty="true" />
    <FindColumn name="VisitUid" visible="false" storeproperty="true" />
    <FindColumn name="CreatedDate" caption="Created Date" visible="true" datatype="date" width="90"/>
    <FindColumn name="RequestingName" caption="Requesting Provider" visible="true" width="150" />
  </ViewPatientOutboundReferralFilter>
  <FeeScheduleFeeAA rowcount="3">
    <column row="0" rowspan="3" caption="Code" width="50" name="Procedure.Code" sort="true" index="name" />
    <column row="0" rowspan="3" caption="Description" relwidth="100%" width="80" AutoWidth="false" name="Procedure.ShortDescription" sort="true" />
    <column row="0" rowspan="3" caption="Amount Allowed" width="60" AutoWidth="false" name="Fee" IsEditable="true" datatype="currency" />
    <column row="0" rowspan="3" caption="Global Period" width="40" AutoWidth="false" name="GlobalPeriodDays" IsEditable="true" datatype="number" decimalPlaces="0" minValue="0" maxValue="1000" />
    <column row="0" colspan="5" caption="Coinsurance" />
    <column row="1" colspan="2" caption="Insurance Percent" />
    <column row="2" caption=" " width="30" AutoWidth="false" name="RadioInsurancePercent" IsEditable="true" datatype="radio" radioOrientation="vertical" radioItems=" " />
    <column row="2" caption="Value" width="70" AutoWidth="false" name="InsurancePercent" IsEditable="true" datatype="number" decimalPlaces="0" minValue="0" maxValue="100" />
    <column row="1" colspan="2" caption="Insurance Plan" />
    <column row="2" caption="PCP/Specialist" width="95" AutoWidth="false" name="RadioInsurancePlanPhysician" IsEditable="true" datatype="radio" radioOrientation="vertical" radioItems=" " />
    <column row="2" caption="Other" width="55" AutoWidth="false" name="RadioInsurancePlanOther" IsEditable="true" datatype="radio" radioOrientation="vertical" radioItems=" " />
    <column row="1" rowspan="2" caption="Copay Amount" width="70" AutoWidth="false" name="FixedCopayAmount" datatype="currency" IsEditable="true" />
    <column row="0" rowspan="3" caption="Contract Type" width="55" AutoWidth="false" name="ContractTypeCode.Name" sort="true"/>
    <column row="0" rowspan="3" caption="Family Planning" width="55" AutoWidth="false" name="FamilyPlanning" IsEditable="true" datatype="bool" />
    <column row="0" rowspan="3" caption="Alt Insurance Plan" width="55" AutoWidth="false" name="UseAlternateInsurancePlan" IsEditable="true" datatype="bool" />
    <column row="0" rowspan="3" caption="Edit Billing Rule" width="70" visible="false" IsEditable="true" datatype="CustomCellType" celltype="iMedica.Prm.Client.UI.BaseControls.Spread.PrmNeoCellImageButton,iMedica.Prm.Client.UI.BaseControls" ShowSortIndicator="false" ImageResourceName="iMedica.Prm.Client.UI.BaseControls.Icons.BillingRule.png" ImageResourceAssembly="iMedica.Prm.Client.UI.BaseControls" sort="false" />
  </FeeScheduleFeeAA>
</spread>

      

+3


source to share


3 answers


This is a pretty trivial problem in XSLT. Given a well-formed input like:

XML

<root>
    <column name="Selected" AutoWidth="false" IsEditable="true" datatype="bool" width="20"/>
    <column width="40" AutoWidth="false" name="ExternalIdOrEmpty" index="XIDname" sort="true"/>
    <column width="40" name="Tax Rate" index="TRname" sort="true" AutoWidth="false"/>
    <column width="40" name="Total Tax" index="TTname" sort="true"/>
    <column name="Tax Deductible" index="TDname" sort="true"/>
</root>

      

the following stylesheet:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="column/@width[not(../@AutoWidth)]">
    <xsl:copy/>
    <xsl:attribute name="AutoWidth">False</xsl:attribute>
</xsl:template>

</xsl:stylesheet>

      



will return:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <column name="Selected" AutoWidth="false" IsEditable="true" datatype="bool" width="20"/>
  <column width="40" AutoWidth="false" name="ExternalIdOrEmpty" index="XIDname" sort="true"/>
  <column width="40" name="Tax Rate" index="TRname" sort="true" AutoWidth="false"/>
  <column width="40" AutoWidth="False" name="Total Tax" index="TTname" sort="true"/>
  <column name="Tax Deductible" index="TDname" sort="true"/>
</root>

      


This matches an attribute width

that sibling does not have AutoWidth

, copies it and adds the missing sibling. Here I have limited the area to only elements column

, but you can expand it to any element by doing:

<xsl:template match="@width[not(../@AutoWidth)]">

      

+6


source


the xpath: //column[@width and not(@AutoWidth)]

.

Explanation:

  • //column

    finds all elements <column ...>

  • [...]

    contains predicates
  • @width

    checks for the presence of an attribute @widht

  • not(@AutoWidth)

    checks for the absence of an attribute @AutoWidth

    .

I have used xpath tester at freeformatter.com for testing.



I added an element <foo>

to make it XML well formatted. That is, this was the actual xml I used for testing:

<foo>
  <column name="Selected" AutoWidth="false" IsEditable="true" datatype="bool" width="20"/>
  <column width="40" AutoWidth="false" name="ExternalIdOrEmpty" index="XIDname" sort="true"/>
  <column width="40" name="Tax Rate" index="TRname" sort="true" AutoWidth="false"/>
  <column width="40" name="Total Tax" index="TTname" sort="true"/>
  <column name="Tax Deductible" index="TDname" sort="true"/>
</foo>

      

Then this is the xpath: //column[@width and not(@AutoWidth)]

He chooses only one element <column index="TTname" name="Total Tax" sort="true" width="40"/>

. I believe this is what you need.

+4


source


There is another quick solution with grep. It needs a bash shell for example. one from git is bash from windows.

cat lines.txt | grep -P -v 'AutoWidth="[^"]*"' | grep -P 'width="[^"]*"'

      

Explanation:

  • cat lines.txt

    - here your data comes from
  • grep -P'

    allows you to simplify perl syntax
  • grep -v

    contains only inconsistent lines
  • "[^"]*"

    matches all values โ€‹โ€‹between quotes, but no further after the first quote

This is the output with your example data:

4->  <column width="40" name="Total Tax" index="TTname" sort="true"/>

      

+1


source







All Articles