OK, das OP hat mich davon überzeugt, dass während the other question mentioned ein überlappendes Thema hat, die Tatsache, dass die verbotene Zeichenfolge an allen Standorten verboten ist, nicht nur als Präfix, Dinge kompliziert genug, um eine separate Antwort zu verlangen, zumindest für die XSD 1.0 Fall. (Ich begann, diese Antwort als Ergänzung zu meiner Antwort auf die andere Frage hinzuzufügen, und es wurde zu groß.)
Es gibt zwei Ansätze, die man hier verwenden kann.
Zuerst in XSD 1.1, eine einfache Behauptung der Form
not(matches($v, 'FILENAME'))
sollte die Arbeit erledigen.
Zweitens, wenn man gezwungen ist, mit einem XSD 1.0 Prozessor zu arbeiten, braucht man ein Muster, das alle und nur Zeichenfolgen, die die verbotene Teilzeichenfolge (hier 'FILENAME') nicht enthalten.
Eine Möglichkeit, um sicherzustellen, dass das Zeichen "F" nie in der Eingabe auftritt. Das ist zu drastisch, aber es macht den Job: Strings, die nicht das erste Zeichen der verbotenen Zeichenfolge enthalten, enthalten die verbotene Zeichenfolge nicht.
Aber was von Strings, die ein Vorkommen von "F" enthalten? Sie sind in Ordnung, solange kein "F" von der Zeichenfolge "ILENAME" gefolgt wird.
diesem letzten Punkt abstrakter Einlochen, können wir sagen, dass jede gültige Zeichenkette (eine beliebige Zeichenfolge, die nicht die Zeichenfolge ‚Dateiname‘ enthält) kann in zwei Teile unterteilt werden:
- Präfix die nicht enthält Vorkommen des Zeichens 'F'
- null oder mehr Vorkommen von 'F', gefolgt von einem String, der nicht mit 'ILENAME' übereinstimmt und kein 'F' enthält.
Das Präfix ist einfach zu entsprechen: [^F]*
.
Die Strings, die mit F beginnen, aber nicht mit 'FILENAME' übereinstimmen, sind etwas komplizierter; genauso wie wir nicht alle Vorkommnisse von "F" ächten wollen, wollen wir auch nicht "FI", "FIL" usw. verbieten - aber jedes Vorkommen einer solchen gefährlichen Kette muss entweder von der Ende der Zeichenfolge, oder durch einen Buchstaben, der nicht mit dem nächsten Buchstaben der verbotenen Zeichenfolge übereinstimmt, oder durch ein anderes 'F', das eine andere Region beginnt, die wir testen müssen. Also für jeden richtigen Präfix der verbotenen Zeichenfolge, schaffen wir einen regulären Ausdruck der Form
$prefix || '([^F' || next-character-in-forbidden-string || ']'
|| '[^F]*'
Dann kommen wir alle diese regulären Ausdrücke mit oder Bars.
Das Endergebnis ist in diesem Fall so etwas wie die folgenden (I newlines hier und da eingefügt haben, um es zu erleichtern, lesen, vor der Verwendung, werden sie wieder herausgenommen werden müssen):
[^F]*
((F([^FI][^F]*)?)
|(FI([^FL][^F]*)?)
|(FIL([^FE][^F]*)?)
|(FILE([^FN][^F]*)?)
|(FILEN([^FA][^F]*)?)
|(FILENA([^FM][^F]*)?)
|(FILENAM([^FE][^F]*)?))*
Zwei Punkte zu beachten:
- XSD Reguläre Ausdrücke sind implizit verankert; Wenn Sie dies mit einem nicht verankerten Evaluator für reguläre Ausdrücke testen, werden die korrekten Ergebnisse nicht erzielt.
- Es mag auf den ersten Blick nicht offensichtlich sein, warum die Alternativen in der Auswahl alle mit
[^F]*
statt .*
enden. Das Nachdenken über die Zeichenfolge 'FEEFIFILENAME' kann helfen. Wir müssen alle Auftreten von "F" überprüfen, um sicherzustellen, dass es nicht von "ILENAME" gefolgt wird.
Mögliches Duplikat [XSD Einschränkung, dass eine passende String negiert] (http://stackoverflow.com/questions/9889206/xsd-restriction-that-negates-a-matching-string) – CSchulz
Nicht, weil in dupliziert meiner case de string FILENAME tritt in jedem Teil der Zeichenfolge nicht nur beim Start auf – Jpff
Ja, es ist ein Duplikat. Jede in den Antworten auf diese Frage beschriebene Methode gilt für diese Frage: Verwenden Sie eine Assertion, um zu bestätigen, dass der Wert FILENAME nicht als Teilzeichenfolge hat, oder schreiben Sie einen regulären Ausdruck, der Zeichenfolgen ohne F entspricht, optional gefolgt von Zeichenfolgen, die F und beginnen Fortfahren mit Nicht-I oder Anfang FI und Fortfahren mit Nicht-L, oder ... –