public function getBaseRegex() {
if ( is_null( $this->baseRegex ) ) {
$this->baseRegex = [ 0 => '', 1 => '' ];
+ $allGroups = [];
foreach ( $this->names as $name ) {
$magic = MagicWord::get( $name );
$case = intval( $magic->isCaseSensitive() );
foreach ( $magic->getSynonyms() as $i => $syn ) {
// Group name must start with a non-digit in PCRE 8.34+
$it = strtr( $i, '0123456789', 'abcdefghij' );
- $group = "(?P<{$it}_{$name}>" . preg_quote( $syn, '/' ) . ')';
+ $groupName = $it . '_' . $name;
+ $group = '(?P<' . $groupName . '>' . preg_quote( $syn, '/' ) . ')';
+ // look for same group names to avoid same named subpatterns in the regex
+ if ( isset( $allGroups[$groupName] ) ) {
+ throw new MWException(
+ __METHOD__ . ': duplicate internal name in magic word array: ' . $name
+ );
+ }
+ $allGroups[$groupName] = true;
if ( $this->baseRegex[$case] === '' ) {
$this->baseRegex[$case] = $group;
} else {