| ## X3D Regular Expressions (regexes) |

> Overview | Design Considerations and Whitespace | X3D Patterns | XML Patterns | References | Tools | X3D Resources | Contact

X3D Regular Expressions (regexes) are used to validate the correctness of string and numeric array values in an X3D scene.

> XML | DOCTYPE | Bool | Color | ColorRGBA | Double | Float | Image | Int32 | Rotation | String | Time | Vec2 | Vec3 | Vec4 | Matrix3 | Matrix4 | bboxSize

### 🔖 Overview

Regular expressions (regexes) define string grammars that efficiently and rigorously define allowable character patterns making up a data value.

Regexes themselves are carefully defined sequences of characters that form a search pattern, mainly used for string pattern matching. For example, this technique allows detection of well-formed (or incorrect) MFVec3f arrays of three-tuple floats in an X3D scene.

X3D regexes are utilized judiciously when the base types of XML Schema are insufficient to capture the necessary richness of X3D content validation. Like all aspects of X3D Schema validation, regex validation is typically high performance and optional for end-user content display.

Note that not all regex languages are completely consistent, thus small (but fundamentally important) variations can occur. This work strictly follows regex syntax for XML Schema, which in turn permits consistent application using other variations of regex languages.

Interestingly, various data validation tools provide expressive power that is able to validate values to different degrees of fidelity.

1. DOCTYPE (DTD). DOCTYPE validation can only check that attribute values are strings. In some cases, a strict set of allowed enumeration values is defined (such as legal names for profiles and components).
2. XML Schema. Schema validation can check a large set of built-in data types. However, XML Schema validation is typically not able to fully check the correctness of array values. For example, an SFVec3f triplet (3-tuple) or an MFVec3f array can be checked to only contain floating-point values, but cannot be checked to have a multiple of three floats.
3. Regular expressions (regexes). Regular expressions can define any regular grammar, and thus have arbitrary expressive power. Although definitions may be tricky to define, character patterns of arbitrary complexity are theoretically achievable.
4. Regexes found on this page are included in the data-type definitions of each X3D XML Schema and X3D Unified Object Model (X3DUOM).

X3D Regular Expressions are an important part of X3D Quality Assurance (QA) to maximize the correctness of X3D scene content.

### 🔖 Design Considerations

General regex design considerations for X3D XML Schema include the following.

1. Regex constructs that are inconsistently implemented across major programming languages are avoided.
2. Careful design allows use of regexes that can be adapted for usage in XML, ClassicVRML, JavaScript/JSON, Java and other language environments.
3. For numeric types, leading sign characters (`+` or `-`) are optionally present.
4. For numeric types, leading zeroes are not allowed, except for an optional leading zero preceding the decimal point when the significand is only fractional.
5. A required mantissa (integer or floating point) is represented as `0|[1-9][0-9]*` (meaning either a solitary `0` or else a single non-zero digit followed by an optional number of additional digits).
6. The fractional part (to the right of the decimal point) can be represented as `[0-9]*`
7. The decimal separator is the symbol used to separate the integer part from the fractional part of a decimal number. The period character `.` is used for all such X3D values, and is escaped as `\.` when written in a regex.
8. Scientific notation starts with upper or lower-case `E`, is optionally positive or negative `([Ee][+-]?[0-9]+)?` and can be appended to float expressions. For integer expressions, nonnegative scientific notation `([Ee][+]?[0-9]+)?` can be appended.
9. Regex anchors are implicit and not included in XML Schema and X3DUOM regexes. Note that strict consumption of all value characters gets performed by these regexes. The anchor characters are necessary for regex101 engine unit testing so that otherwise-illegal values are not rejected (in MF tests).

Pattern components are used repeatedly in this design:

- Regex anchor matching: `^` (line start) and `$` (line end)
- Whitespace matching:
  - `\s*` (optional whitespace outside all values)
  - `\s+` (required whitespace within tuple values)
  - `\s*,?\s*` (required whitespace with optional single comma, following each n-tuple value)
- Group repetition: `{n}` repeats the preceding group n number of times.
- Boolean-value matching: `true|false`
- Hexadecimal matching: `0x[0-9a-fA-F]{1,16}`
- Scientific notation: `([Ee][+-]?[0-9]+)?`
- Integer-value matching: `[+-]?(0|[1-9][0-9]*)([Ee][+-]?[0-9]+)?`
- Float-value matching: `([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)`
- Nonnegative float [0..1] matching: `([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)`

#### 🔖 Disallowed values and Negative Lookahead

Some values may be numerically correct but not permitted.

- For example, numbers using scientific notation in the range `[0..1]` such as `3.0E-6` which nevertheless have a leading digit in range `[2..9]`.

Negative Lookahead filters have potential to disqualify attributes that contain illegal values.

- W3C Recommendation for XML Schema (XSD): Regular Expressions does not support this construct, perhaps to avoid the possibility of computational denial-of-service (DoS) attacks.
- `(?!((0|0\.0*|\.0+)\s+){3})` prohibits `0 0 0` and `0.0 0.0 0.0` (for example).
- `(?!\s*,\s*,)` prohibits multiple adjacent commas in intermediate whitespace, for example `0 0 0, ,0 0 0` is an illegal set of MFColor values.

This can be a useful construct since some specific values are disallowed in X3D. One such instance is that any zero vector is illegal as initial axis triplet of an SFRotation.

Alternate (stricter and more complex) regexes might someday get included in X3DUOM, but current regular expressions are powerful and satisfactory.

#### 🔖 Whitespace Considerations

Intermediate commas are treated as whitespace, but are only allowed between each singleton value. For example, SFVec3f 3-tuple values within an MFVec3f array do not contain comma characters (but may be separated by commas and whitespace). Experience has shown that misplaced commas are a crucial indicator of malformed tuple values in large float arrays.

- Reference: X3D Extensible Markup Language (XML) encoding, Clause 5 Encoding of fields, 5.1.2 Description

For XML Schema to enable any inclusion of intermediate commas as whitespace characters in MultiField (MF) array types, native XML Schema datatypes typically cannot be used directly. In order to ensure strict validation, regex patterns must be used instead.

- Patterns to consume outer whitespace are prepended/appended for each type. Type regexes also allow multiple inner whitespace characters, optionally including a single comma between individual MF array values.
- Of note is that regex patterns only apply to base type `xs:string`, and so further application of strong XML Schema typing (i.e. `base="xs:double"` etc.) is not simultaneously possible when allowing commas as whitespace.
- Implementation of the `\s` regex pattern can vary in Perl Compatible Regular Expressions PCRE library (C, PHP, R, etc.) and some other implementations to accept a number of characters such as vertical whitespace `\v` including vertical tab `cK`, form feed `\f`, line feed, paragraph or line separator, and special Unicode characters. Thus an even stricter pattern `( \n\r\t)*` might conceivably be used instead of pattern `\s` in order to strictly honor whitespace characters defined in ClassicVRML grammar.
- Similar to some programming languages, `MFVec` patterns typically allow a single trailing comma at the end of an array.

Potential whitespace variations in scene content are not an issue if X3D Canonicalization (C14N) has been applied to an X3D scene.

### 🔖 X3D Patterns

The following regex patterns are used in X3D XML Schema, X3D Unified Object Model (X3DUOM) and other validation tools.

X3D datatype regex patterns
🔖 SFBool and ordered list 🔖 MFBool: each SFBool value can be either `true` or `false`. Note that VRML97 values `TRUE` and `FALSE` are capitalized and illegal in X3D. | X3D Architecture Specification: 5.3.1 SFBool and MFBool X3D Schema documentation: simpleType SFBool, MFBool X3D Tooltips: SFBool, MFBool regex101: SFBool eval and unit tests, MFBool eval and unit tests
#### SFBool matching: single true or false value. XML Schema: `<xs:restriction base="xs:boolean"/>` Regex pattern: `^\s*(true|false)\s*$`
#### MFBool matching: ordered list of zero or more SFBool values. XML Schema: `<xs:list itemType="xs:boolean"/>` Regex pattern: `^\s*((true|false)\s*,?\s*)*$`
🔖 SFImage and ordered list 🔖 MFImage: each SFImage value describes pixels in a 2D image. SFImage fields contain three nonnegative integers representing width, height and number of components [1..4] in the image, followed by width�height hexadecimal or integer values representing pixel colors in the image. | 🔖 X3D Architecture Specification: 5.3.1 SFImage and MFImage X3D Schema documentation: simpleType SFImage, MFImage X3D Tooltips: SFImage, MFImage regex101: SFImage eval and unit tests, MFImage eval and unit tests Alternative original example: regex101: SFImage (screenshot)
#### SFImage matching: two nonnegative integers, followed by integer [0-4], followed by a hexadecimal array, values Regex pattern: `^\s*([+]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?\s+){2}[+]?[0-4](\s+(0x[0-9a-fA-F]{1,16}|[+]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?))*\s*$`
#### MFImage matching: ordered list of zero or more SFImage values. Regex pattern: `^\s*(([+]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?\s+){2}[+]?[0-4](\s+(0x[0-9a-fA-F]{1,16}|[+]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?))*\s*,?\s*)*$`
🔖 SFInt32 and ordered list 🔖 MFInt32: each SFInt32 value is an unrestricted integer, with optional scientific-notation exponent. | X3D Architecture Specification: 5.3.1 SFInt32 and MFInt32 X3D Schema documentation: simpleType SFInt32, MFInt32 X3D Tooltips: SFInt32, MFInt32 regex101: SFInt32 eval and unit tests, MFInt32 eval and unit tests
#### SFInt32 matching: integer value with optional scientific notation. XML Schema: `<xs:restriction base="xs:integer"/>` Regex pattern: `^\s*[+-]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?\s*$`
#### MFInt32 matching: ordered list of zero or more SFInt32 values. Regex pattern: `^\s*([+-]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?\s*,?\s*)*$`
🔖 SFFloat and ordered list 🔖 MFFloat: each SFFloat value is a single-precision floating-point number. 🔖 SFDouble and ordered list 🔖 MFDouble: each SFDouble value is a double-precision floating-point number. 🔖 SFTime and ordered list 🔖 MFTime: each SFTime value is a double-precision floating-point number. | X3D Architecture Specification: 5.3.5 SFFloat and MFFloat, 5.3.4 SFDouble and MFDouble, 5.3.15 SFTime and MFTime X3D Schema documentation: simpleType SFFloat, MFFloat, SFDouble, MFDouble, SFTime, MFTime X3D Tooltips: SFFloat, MFFloat, SFDouble, MFDouble, SFTime, MFTime regex101: SFFloat/SFDouble/SFTime eval and unit tests, MFFloat/MFDouble/MFTime eval and unit tests
#### SFFloat, SFDouble and SFTime matching: floating-point value with optional scientific notation. XML Schema: `<xs:restriction base="xs:float"/>` and `<xs:restriction base="xs:double"/>` Regex pattern: `^\s*([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*$`
#### MFFloat/MFDouble/MFTime matching: ordered list of zero or more SFFloat/SFDouble/SFTime values. Regex pattern: `^\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*$`
🔖 SFVec2f and ordered list 🔖 MFVec2f: each SFVec2f value is a 2-tuple set of single-precision floating point numbers. 🔖 SFVec2d and ordered list 🔖 MFVec2d: each SFVec2d value is a 2-tuple set of double-precision floating point numbers. | X3D Architecture Specification: 5.3.17 SFVec2f and MFVec2f, 5.3.16 SFVec2d and MFVec2d X3D Schema documentation: simpleType SFVec2f, MFVec2f, SFVec2d, MFVec2d X3D Tooltips: SFVec2f, MFVec2f, SFVec2d, MFVec2d regex101: SFVec2f/SFVec2d eval and unit tests, MFVec2f/MFVec2d eval and unit tests
#### SFVec2f/SFVec2d matching: two-tuple floating-point values with optional scientific notation. Regex pattern: `^\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){1}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*$`
#### MFVec2f/MFVec2d matching: ordered list of zero or more SFVec2f/SFVec2d values. Regex pattern: `^\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){1}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*$`
🔖 SFVec3f and ordered list 🔖 MFVec3f: each SFVec3f value is a 3-tuple triplet of single-precision floating point numbers. 🔖 SFVec3d and ordered list 🔖 MFVec3d: each SFVec3d value is a 3-tuple triplet of double-precision floating point numbers. | X3D Architecture Specification: 5.3.19 SFVec3f and MFVec3f, 5.3.18 SFVec3d and MFVec3d X3D Schema documentation: simpleType SFVec3f, MFVec3f, SFVec3d, MFVec3d X3D Tooltips: SFVec3f, MFVec3f, SFVec3d, MFVec3d regex101: SFVec3f/SFVec3d eval and unit tests (non-negative), MFVec3f/MFVec3d eval and unit tests
#### SFVec3f/SFVec3d matching: three-tuple floating-point values with optional scientific notation. Regex pattern: `^\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){2}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*$`
#### MFVec3f/MFVec3d matching: ordered list of zero or more SFVec3f/SFVec3d values. Regex pattern: `^\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){2}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*$`
🔖 SFVec4f and ordered list 🔖 MFVec4f: each SFVec4f value is a 4-tuple set of single-precision floating point numbers. 🔖 SFVec4d and ordered list 🔖 MFVec4d: each SFVec4d value is a 4-tuple set of double-precision floating point numbers. | X3D Architecture Specification: 5.3.21 SFVec4f and MFVec4f, 5.3.20 SFVec4d and MFVec4d X3D Schema documentation: simpleType SFVec4f, MFVec4f, SFVec4d, MFVec4d X3D Tooltips: SFVec4f, MFVec4f, SFVec4d, MFVec4d regex101: SFVec4f/SFVec4d eval and unit tests, MFVec4f/MFVec4d eval and unit tests
#### SFVec4f/SFVec4d matching: four-tuple floating-point values with optional scientific notation. Regex pattern: `^\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*$`
#### MFVec4f/MFVec4d matching: ordered list of zero or more SFVec4f/SFVec4d values. Regex pattern: `^\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*$`
🔖 SFColor and ordered list 🔖 MFColor: each SFColor value is a 3-tuple set of single-precision floating point numbers, each ranging from [0,1] inclusive. | X3D Architecture Specification: 5.3.2 SFColor and MFColor X3D Schema documentation: simpleType SFColor, MFColor X3D Tooltips: SFColor, MFColor regex101: SFColor eval and unit tests, MFColor eval and unit tests
#### SFColor matching: three-tuple floating-point values with optional scientific notation, bounded. Regex pattern: `^\s*(([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s+){2}([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s*$`
#### MFColor matching: ordered list of zero or more SFColor values. Regex pattern: `^\s*((([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s+){2}([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s*,?\s*)*$`
🔖 SFColorRGBA and ordered list 🔖 MFColorRGBA: each SFColorRGBA value is a 4-tuple set of single-precision floating point numbers, each ranging from [0,1] inclusive. | X3D Architecture Specification: 5.3.3s SFColorRGBA and MFColorRGBA X3D Schema documentation: simpleType SFColorRGBA, MFColorRGBA X3D Tooltips: SFColorRGBA, MFColorRGBA regex101: SFColorRGBA eval and unit tests, MFColorRGBA eval and unit tests
#### SFColorRGBA matching: four-tuple floating-point values with optional scientific notation, bounded. Regex pattern: `^\s*(([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s+){3}([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s*$`
#### MFColorRGBA matching: ordered list of zero or more SFColorRGBA values. Regex pattern: `^\s*((([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s+){3}([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s*,?\s*)*$`
🔖 SFMatrix3f and ordered list 🔖 MFMatrix3f: each SFMatrix3f value is a 3x3 nine-tuple triplet of single-precision floating point numbers. 🔖 SFMatrix3d and ordered list 🔖 MFMatrix3d: each SFMatrix3d value is a 3x3 nine-tuple triplet of double-precision floating point numbers. | X3D Architecture Specification: 5.3.19 SFMatrix3f and MFMatrix3f, 5.3.18 SFMatrix3d and MFMatrix3d X3D Schema documentation: simpleType SFMatrix3f, MFMatrix3f, SFMatrix3d, MFMatrix3d X3D Tooltips: SFMatrix3f, MFMatrix3f, SFMatrix3d, MFMatrix3d regex101: SFMatrix3f/SFMatrix3d eval and unit tests, MFMatrix3f/MFMatrix3d eval and unit tests
#### SFMatrix3f/SFMatrix3d matching: 3x3 nine-tuple floating-point values with optional scientific notation. Regex pattern: `^\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){8}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*$`
#### MFMatrix3f/MFMatrix3d matching: ordered list of zero or more SFMatrix3f/SFMatrix3d values. Regex pattern: `^\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){8}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*$`
🔖 SFMatrix4f and ordered list 🔖 MFMatrix4f: each SFMatrix4f value is a 4x4 sixteen-tuple set of single-precision floating point numbers. 🔖 SFMatrix4d and ordered list 🔖 MFMatrix4d: each SFMatrix4d value is a 4x4 sixteen-tuple set of double-precision floating point numbers. | X3D Architecture Specification: 5.3.21 SFMatrix4f and MFMatrix4f, 5.3.20 SFMatrix4d and MFMatrix4d X3D Schema documentation: simpleType SFMatrix4f, MFMatrix4f, SFMatrix4d, MFMatrix4d X3D Tooltips: SFMatrix4f, MFMatrix4f, SFMatrix4d, MFMatrix4d regex101: SFMatrix4f/SFMatrix4d eval and unit tests, MFMatrix4f/MFMatrix4d eval and unit tests
#### SFMatrix4f/SFMatrix4d matching: 4x4 sixteen-tuple floating-point values with optional scientific notation. Regex pattern: `^\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){15}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*$`
#### MFMatrix4f/MFMatrix4d matching: ordered list of zero or more SFMatrix4f/SFMatrix4d values. Regex pattern: `^\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){15}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*$`
🔖 SFRotation and ordered list 🔖 MFRotation: each SFRotation value is a 4-tuple set of single-precision floating point numbers, representing normalized 3-tuple axis of rotation, followed by angle of rotation in angle base units (default is radians). Note: it is reject illegal axis vector using negative lookahead `(?!((0|0\.0*|\.0+)\s+){3})` Candidate subtypes: stricter enforcement that magnitudes of axis values are not greater than 1. | X3D Architecture Specification: 5.3.21 SFRotation and MFRotation X3D Schema documentation: simpleType SFRotation, MFRotation X3D Tooltips: SFRotation, MFRotation regex101: SFRotation eval and unit tests, MFRotation eval and unit tests
#### SFRotation matching: four-tuple floating-point values with optional scientific notation. Regex pattern: `^\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*$`
#### MFRotation matching: ordered list of zero or more SFRotation values. Regex pattern: `^\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*$`
🔖 SFString and ordered list 🔖 MFString: each SFString value is an unquoted set of characters, while each MFString consists of quoted SFString values separated by whitespace (including commas). | X3D Architecture Specification: 5.3.14 SFString and MFString X3D Schema documentation: simpleType SFString, MFString X3D Tooltips: SFString, MFString
#### SFString matching: unquoted string value. XML Schema: `<xs:restriction base="xs:string"/>` Regex pattern: none.
#### MFString matching: ordered list of zero or more quoted SFString values. XML Schema: `<xs:list itemType="xs:string"/>` TODO. Is there a practical regex that can match pairs of unescaped quotation marks?
🔖 Bounding box size (bboxSize): a 3-tuple SFVec3f value with each x,y,z component in nonnegative range [0,+infinity) or else `-1 -1 -1`. Default `bboxSize='-1 -1 -1'` is a sentinel value indicating that no bounding box value has been provided.`` | X3D Architecture Specification: 10.2.2 Bounding boxes X3D Schema documentation: simpleType boundingBoxSizeType X3D Tooltips: Anchor.bboxSize regex101: bboxSize eval and unit tests
#### bboxSize matching: three-tuple floating-point values with optional scientific notation, bounded non-negative or else -1 -1 -1 sentinel value. Regex pattern: `^\s*((([+]?(((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){2}([+]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*)|((\-1(\.(0)*)?([Ee][+-]?[0]+)?\s+){2}\-1(\.(0)*)?([Ee][+-]?[0]+)?)\s*)?$`

TODO. Several pattern possibilities for urls/URNs are conceivable. Adding an MFString url regex pattern is likely useful.

X3D Java Scene Access Interface Library (X3DJSAIL) provides a set of unit tests in `org.web3d.x3d.tests.FieldObjectTests` to check these regexes against default and alternative values.

A scratch pad of various experimental regexes is found in X3dRegularExpressionTests.txt.

### 🔖 XML Patterns

The Extensible Markup Language (XML) provides several useful definitions and restrictions on string types.

- `CDATA` is Character Data, or unrestricted text. (XML Recommendation) (XML Schema)
- `NMTOKEN` is Name Token to match naming requirements for legal characters with no spaces. (XML Recommendation) (XML Schema)
- `xs:token` is similar to NMTOKEN but allows single-occurrence whitespace characters within the string. No leading or trailing spaces can occur. (XML Schema)

X3D Scene Authoring Hints: Validation describe all initial XML headers for X3D.

Note that regex checking of expressions within the X3D XML Schemas are needed, since literal validation of those attribute values gets performed by various authoring tools (such as Altova XMLSpy).

Regex testing for XML-related constructs by X3dDoctypeChecker.java include the following.

XML and DOCTYPE regex patterns
XML declaration as part of the document prolog: `<\\?xml version=(\"|')1.(0|1)(\"|') encoding=(\"|')UTF-(8|16)(\"|')\\?>`
XML declaration, case insensitive: `<\\?xml version=(\"|')1.(0|1)(\"|') encoding=(\"|')(U|u)(T|t)(F|f)-(8|16)(\"|')\\?>`
Experimental X3D 4.0 DOCTYPE: `<!DOCTYPE X3D PUBLIC(\\s)+\"ISO//Web3D//DTD X3D 4.0//EN\"(\\s)+\"https://www.web3d.org/specifications/x3d-4.0.dtd\"(\\s)*(>|\\[)`
Approved X3D 3.3 DOCTYPE: `<!DOCTYPE X3D PUBLIC(\\s)+\"ISO//Web3D//DTD X3D 3.3//EN\"(\\s)+\"https://www.web3d.org/specifications/x3d-3.3.dtd\"(\\s)*(>|\\[)`
X3D 3.2 DOCTYPE: `<!DOCTYPE X3D PUBLIC(\\s)+\"ISO//Web3D//DTD X3D 3.2//EN\"(\\s)+\"https://www.web3d.org/specifications/x3d-3.2.dtd\"(\\s)*(>|\\[)`
X3D 3.1 DOCTYPE: `<!DOCTYPE X3D PUBLIC(\\s)+\"ISO//Web3D//DTD X3D 3.1//EN\"(\\s)+\"https://www.web3d.org/specifications/x3d-3.1.dtd\"(\\s)*(>|\\[)`
X3D 3.0 DOCTYPE: `<!DOCTYPE X3D PUBLIC(\\s)+\"ISO//Web3D//DTD X3D 3.0//EN\"(\\s)+\"https://www.web3d.org/specifications/x3d-3.0.dtd\"(\\s)*(>|\\[)`

🔖 Error-detection regexes are applied as part of X3D Examples Archives build.xml checking, see target `processScenes.regularExpressionChecks` for invocation details.

Error-Detection Patterns
Malformed floating-point numbers (multiple decimal points, etc.), property name="regexGarbledFloats" `(\s|,|"|')(((\+|-)?((\.\d+)|(\d+\.\d*))((E|e)(\+|-)?\d+)?(\.|\+|-)+(\d*))|(\d+((\+|-)\d+)+))(\s|,|"|')`
Excess leading zeroes, property name="regexLeadingZeroes" `(\s|,|"|')(\+|-)?0\d+(\.\d*)?((E|e)(\+|-)?\d+)?(\s|,|"|')`
... which is preceded by negative look-behind checks to avoid flagging software version numbers, property name="regexNegativeLookBehinds" `?<!address=)(?<!pecification)(?<!ection)(?<!aragraph)(?<!CosmoPlayer)(?<!CAD Exchanger)`

🔖 Error-correction regexes are also possible using XPath `replace(source,pattern,replacement)` function. For repeatability the `pattern` being matched must be a strict regular expression rather than a literal.

Error-Correction Patterns
Remove whitespace commas from appropriately typed numeric values `normalize-space(replace(., ',', ' '))`
Omit trailing decimal point if followed by whitespace `normalize-space(replace(concat(replace(., ',', ' '),' '),'([.][ ])', ' '))`
Insert 0 if negative fraction encountered, e.g. `-.123` to `-0.123` `replace(normalize-space(replace(., ',', ' ')),'([-][.])', '-0.')`

### 🔖 References

The following references provide useful additional information about X3D, regular expressions and data validation.

1. Apache Ant Manual: replaceregexp, regexp type, regexp type mapper. Also Ant-contrib propertyregex.
2. Davis, Mark. Unicode Regular Expression Guidelines, 2016.
3. Friedl, Jeffrey E.F., Mastering Regular Expressions: Understand Your Data and Be More Productive Third Edition, O'Reilly and Associates, Sebastopol California, 2009.
4. Goyvaertz, Jan and Levithan, Steven, Regular Expressions Cookbook: Detailed Solutions in Eight Programming Languages, second edition, O'Reilly Media, Sebastopol California, 2012.
5. Python regular expression (regex) library `re` is built into Python (Python regex howto)
6. RegExLib.com regular expression library
7. Regular-expressions.Info website, including XML Schema Regular Expressions and Runaway Regular Expressions: Catastrophic Backtracking.
8. E-mail post: Regular expression checking for malformed floating-point numbers and excess leading zeros
9. Wikipedia: Regular expression article.
10. Wikipedia: Ken Thompson's construction algorithm article.
11. X3D field data types are defined in Annex 5. Field type reference X3D Abstract Specification.
12. World Wide Web Consortium (W3C) Recommendation: XML Schema Definition Language (XSD) 1.1 Part 2 Datatypes with sections on Regular expressions, float checking, etc.
13. X3D Specifications: XML Schema and DOCTYPE Validation include the latest versions of recommended XML Schemas and DOCTYPEs (DTDs) for X3D.
14. X3D Resources provides links to numerous resources supporting X3D and VRML.
    - X3D Quality Assurance (QA) identifies errors and warnings in order to make X3D scene content more portable and reliable. This section provides links to each of the different QA tests that are available.
15. X3D Scene Authoring Hints provide a collection of style guidelines, authoring tips and best practices to improve the quality, consistency and maintainability of X3D Graphics scenes.
    - Validation of X3D Scenes using DTD and XML Schema shows example declarations of DTD and Schema in X3D scenes.
16. X3D Unified Object Model (X3DUOM)
17. X3D Java Scene Access Interface Library (X3DJSAIL)
18. X3D Validator is a Web application that checks X3D scene validity.
19. XML Schema 1.1 Part 2: Datatypes Second Edition, World Wide Web Consortium (W3C) Recommendation. Includes sections on Datatype System, Built-in datatypes and Regular Expressions.

### 🔖 Tools

Links to tools of interest follow. Additional recommendations are welcome.

- Online Regex Tester allows live color-coded testing of regex expressions and corresponding string matches in a browser. (n.b. alternative regex vocabularies offered)
- XML Schema - Regular Expressions offers detailed guidance.

### 🔖 Contact

Questions, suggestions and comments about these resources are welcome. Please send them to Don Brutzman.

The contributions of Roy Walmsley are gratefully acknowledged.

Available online at https://www.web3d.org/specifications/X3dRegularExpressions.html

Version control of this document is maintained at
https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/specifications/X3dRegularExpressions.html

Updated: 3 September 2023