2017-04-20 38 views
3

我使用許多不同的正則表達式實現,因爲這發生在幾個系統上(Linux,Windows,VS,記事本++等);這正是我有一個客戶想要刪除自動調整大小的地方。意圖是使用正則表達式,其中有史以來的工具來找到任何有寬度,但沒有自動寬度的行,然後加上 autowidth。我只是問如何找到它,,但我打算然後使用我在這裏找到的替代字符串中的給定編輯器。我有替換位:我只是沒有想出如何讓另一個遠離另一個。正則表達式匹配一個字符串,但只有當另一個字符串不存在於同一行上的任何地方

使用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") 

我卡住了,把正在躲避我AutoWidth和寬度之間的距離。

這是我的目標

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

我想找到包含

寬度的所有行= 「\ d *」

,但不包含

AutoWidth = 「\ d *」

在同一行上的任何地方。

這意味着只有第4行在上面的示例中符合我的標準。

UPDATE:

我願意使用任何其他工具,將完成這項工作。所以XSLT等都很好。唯一的要求是,該工具通常可在Windows,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

瞭解如何使用HTML解析器和你的日子會更快樂。對於python:'beautifulsoup',對於java:'jsoup',對於php:'DOMDocument'等等...... –

+0

@PedroLobito他的html解析器是什麼類型的?它可以幫助我解決我的XML問題嗎? –

+1

xpath很簡單。正則表達式解決方案看起來很難。 –

回答

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> 

這匹配沒有兄弟AutoWidthwidth屬性,將其複製並添加缺少的兄弟。在這裏我有限的範圍只column元素,但你可以擴展它從做任何元素:

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

這是一個很好的起點。有沒有辦法在應用修復程序時發出整個文檔?我使用正則表達式的原因是因爲我也可以使用替換方面,從而修復文檔。我想我並不清楚這一點。 –

+0

@Dysmondad正是這樣做的:所有沒有被第二個模板匹配的節點都是由* identity transform *模板處理的 - 也就是*被複制的*。 –

+0

謝謝。這可以通過XML插件 - > Transform XML與Notepad ++協同工作。正是我需要的。 –

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"/>。我相信這是你需要的。

1

有使用grep另一個快速的解決方案。它需要一個bash外殼,例如來自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"/> 
相關問題