Любой, кто знает что-нибудь о XML, скажет вам не делать это с помощью обработки регулярных выражений, а с помощью правильного анализатора XML и инструментов XML. Вероятно, это можно сделать с помощью регулярных выражений (но не мной), если вы знаете, что формат файла всегда будет точно таким, как вы его показали, например, с символами новой строки, двойными кавычками и порядком атрибутов точно так же, как в вашем примере. Но если вы введете это в работу, то кто-то, генерирующий XML, через несколько лет спросит StackOverflow, как убедиться, что он может генерировать XML именно в этом формате, потому что принимающее приложение ломается, если атрибуты находятся в неправильном порядке или используйте одинарные кавычки, а не двойные. Итак, вы создаете проблемы на будущее. (Запомните закон Постеля, который в данном случае означает, что вы должны принимать любой правильно сформированный XML, эквивалентный этому XML).
В любом случае, сделать это в XSLT намного проще, чем так, как вы предлагаете. Предполагая, что вы хотите, чтобы оба атрибута совпадали, чтобы элемент считался дубликатом, тогда код:
<xsl:template match="d:entry">
<xsl:copy>
<xsl:for-each-group select="d:index"
group-by="concat(@d:value, '~', @d:title)">
<xsl:copy-of select="current-group()[1]"/>
</xsl:for-each-group>
<xsl:copy-of select="div"/>
</xsl:copy>
</xsl:template>
Кстати, вы сказали "пробел добавлен для удобства чтения". Этот пробел, особенно если он включает переводы строк, будет иметь большое влияние на любое решение регулярных выражений, но никак не повлияет на правильно написанный XSLT.