代码之家  ›  专栏  ›  技术社区  ›  new2ios xav xav

如何更改regex使其在sql server中工作?

  •  0
  • new2ios xav xav  · 技术社区  · 6 年前

    我有以下正则表达式:

    /^((?:(?: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 ,像:

    192.168.10.11|192.168.10.10
    

    我生成 XSD 使用 T-SQL . 使用此正则表达式时,出现以下错误:

    错误消息:正则表达式无效 “/^(?)(?):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附近。

    你知道怎么重写还是在哪里修复吗?

    备注:生成以下正则表达式,但未验证输入:

    /^((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
    

    编辑: 一般来说,我试着检查空白(我需要“没有空白”)。我试着仔细检查以确保列表中的IP也是有效的。显然,从t-sql创建它太复杂了。所以可能只是为了检查空白?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Razvan Socol    6 年前

    尝试删除字符串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]?)(\|?))*"/>
    

    但是,上面的regex接受一个额外的尾部 | . 为了避免这种情况,可以使用以下模式:

    <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 ,以避免与其他语言中的数字相匹配,例如 ৩ (但是你已经编辑了你的问题来避免这个问题)。

        2
  •  1
  •   Gottfried Lesigang    6 年前

    纯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 ),如果 INT 在0到255之间,如果有空格( DATALENGTH VS LEN )等等…

    希望这有帮助