匹配字符串的正则表达式,但仅当同一行中的任何位置不存在另一个字符串时

时间:2017-04-20 14:42:05

标签: regex xslt language-agnostic regex-lookarounds

我正在使用许多不同的Regex实现,因为这发生在几个系统上(Linux,Windows,VS,记事本++等);它就是我有一个客户想要删除自动调整大小的地方。目的是使用正则表达式,其中任何工具都可以找到任何具有宽度但没有自动宽度然后添加自动宽度的行。我只是想问一下如何找到它,但是我打算在我给定的编辑器的替换字符串中使用我在这里找到的东西。我有替换位:我只是没有&#t; t当另一个远离那个时,想出了如何从另一个中取出一个。

使用https://regex101.com/我已尝试过数十个搜索字符串。

这是我搜索字符串的起点,并且尝试了几次尝试在行上的任何位置排除AutoWidth。字符串2和3基本相同,但我不知道还有什么可以尝试。我认为任何适用于后视的东西都适用于前瞻,但正如你所看到的,我甚至不能在后面工作。

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

我卡住了,把自动宽度和宽度之间的距离放在了我的身上。

这些是我的目标

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"/>

我想找到包含

的所有行
  

宽度=&#34; \ d *&#34;

但不包含

  

AutoWidth =&#34; \ d *&#34;

在同一条线上的任何地方。

这意味着上述示例中只有第4行符合我的标准。

更新:

我愿意使用任何其他可以完成工作的工具。所以XSLT等都很好。唯一的要求是该工具通常可在Windows,Linux和Linux上使用。 Mac,AND是开源的或免费的,也是众所周知的。

完整的xml非常庞大。此处的编辑功能限制为30,00个字符,但这是一个很好的样本。

<?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 个答案:

答案 0 :(得分:6)

这在XSLT中是一个相当简单的问题。给出了良好的输入,例如:

<强> 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>

以下样式表:

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>

将返回:

<?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>

这匹配没有兄弟width的{​​{1}}属性,复制它并添加缺少的兄弟。在这里,我仅将范围限制为AutoWidth元素,但您可以通过执行以下操作将其扩展为任何元素:

column

答案 1 :(得分:4)

xpath是这样的://column[@width and not(@AutoWidth)]

说明:

  • //column找到所有<column ...>元素
  • [...]包含谓词
  • @width检查是否存在@widht属性
  • not(@AutoWidth)检查是否缺少@AutoWidth属性。

我使用freeformatter.com上的xpath tester进行测试。

我添加了一个<foo>元素,使其格式良好的XML。即这是我用于测试的实际xml:

<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>

然后,这是xpath://column[@width and not(@AutoWidth)]

它只选择一个项目:<column index="TTname" name="Total Tax" sort="true" width="40"/>。我相信这就是你所需要的。

答案 2 :(得分:1)

grep还有另一个快速解决方案。它需要一个bash shell,例如来自windows的git-bash之一。

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

说明:

  • cat lines.txt - 这是您的数据来自
  • 为了简单起见,
  • grep -P'启用了perl语法
  • grep -v仅保留不匹配的行
  • "[^"]*"匹配引号之间的所有内容,但在第一次引用后不会更进一步

这是您的示例数据的结果:

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