如何更改RegEx以便它在SQL Server中工作?

时间:2018-06-16 11:23:38

标签: regex tsql sql-server-2012 xsd xsd-validation

我有以下正则表达式:

/^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\|?))*$/g

我需要它使用XSD验证输入(由管道分隔的IP地址列表(IP v.4)),如:

192.168.10.11|192.168.10.10

我使用XSD生成T-SQL。当我使用此RegEx时出现以下错误:

  

错误消息:正则表达式无效   " / ^(????(?::( 25 [0-5] | 2 [0-4] [0-9] | [01] [0-9] [0-9])) {3}(?: 25 [0-5] | 2 [0-4] [0-9] | [01] [0-9] [0-9])(\ |?))* $ /克"   靠近偏移5。

知道如何重写它或在哪里修复它?

备注:生成以下RegEx但未验证输入:

/^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)(\|?))*$/g

用于生成的T-SQL:

CREATE XML SCHEMA COLLECTION schFile0000001234 AS 
'<xsd:schema
targetNamespace="http://example.com/brg/"
elementFormDefault="qualified"
xmlns="http://example.com/brg/"
xmlns:mstns="http:/example.com/brg/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="1.0.1"
>
  <xsd:complexType name="ct0000006847_KDK_XXX_Front_Parameters">
    <xsd:sequence>
      <xsd:element name="KDK_XXX_Front_AllowedSourceIPs" minOccurs="1" maxOccurs="1">
        <xsd:simpleType>
          <xsd:restriction base="xsd:string">
            <xsd:minLength value="1"/>
            <xsd:maxLength value="1000"/>
            <xsd:pattern value="/^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\|?))*$/g"/>
          </xsd:restriction>
        </xsd:simpleType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

</xsd:schema>';
GO

编辑:一般情况下,我会尝试检查空白区域(我需要&#34;没有空格&#34;)。我试着做好检查,以确保列表中的IP也是有效的。显然,从T-SQL创建它太复杂了。那么可能只是检查空格?

2 个答案:

答案 0 :(得分:1)

尝试删除字符串start /^和字符串结束*$标记以及/g选项。换句话说,请尝试以下模式:

<xs:pattern value="(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\|?))*"/>

但是,上述正则表达式接受额外的尾随|。为避免这种情况,您可以使用以下模式:

<xs:pattern value="((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))*"/>

我建议使用[0-9]代替\d,以避免匹配其他语言中的数字,例如(但您已经编辑了问题以避免这种情况)。

答案 1 :(得分:1)

使用纯T-SQL(但不在XSD内)的一种方法可能是拆分输入并验证它旧学校

DECLARE @tbl TABLE(ID INT IDENTITY, YourIPList VARCHAR(500));
INSERT INTO @tbl VALUES('192.168.10.11|192.168.10.10');

WITH SplittedAtPipe AS
(
    SELECT ID
          ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS IP_index 
          ,YourIPList
          ,[ip].value('text()[1]','varchar(100)') AS OneIp
    FROM @tbl
    CROSS APPLY(SELECT CAST('<x>' + REPLACE(YourIPList,'|','</x><x>') + '</x>' AS XML) AS IPXml) A
    CROSS APPLY A.IPXml.nodes('/x') B([ip])
) 
,SplittedAtDot AS
(
    SELECT SplittedAtPipe.*
          ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Frg_index 
          ,frg.value('text()[1]','varchar(100)') AS IPFragment
    FROM SplittedAtPipe
    CROSS APPLY(SELECT CAST('<x>' + REPLACE(OneIp,'.','</x><x>') + '</x>' AS XML) AS IPFragment) A
    CROSS APPLY A.IPFragment.nodes('/x') B(frg)
)
SELECT * 
FROM SplittedAtDot;

如果TRY_CAST在0到255之间,如果有空白(INTDATALENGTH,则可以检查每个片段是否为数字(LEN) )等等......

希望这有帮助