Нужно ли реализациям регулярных выражений функция split ()? - PullRequest
3 голосов
/ 18 марта 2012

Существует ли какое-либо приложение для операции регулярного выражения split(), которое не может быть выполнено с помощью одной операции match() (или search(), findall() и т. Д.)?

Например, вместо того, чтобы делать

subject.split('[|]')

вы можете получить тот же результат, позвонив на

subject.findall('[^|]*') 

И почти во всех движках регулярных выражений (кроме .NET и JGSoft) split() не может делать такие вещи, как "разбить на |, если они не экранированы \|", потому что вы " Мне нужно иметь неограниченное количество повторений внутри взгляда.

Так что вместо того, чтобы делать что-то совершенно нечитаемое, как это (вложенные взгляды!)

splitArray = Regex.Split(subjectString, @"(?<=(?<!\\)(?:\\\\)*)\|");

Вы можете просто сделать (даже в JavaScript, который не поддерживает любой вид назад)

result = subject.match(/(?:\\.|[^|])*/g);

Это привело меня к удивлению: есть ли что-нибудь вообще, что я могу сделать в split(), чего невозможно достичь с помощью одного match() / findall() вместо этого? Я готов поспорить, что нет, но я, вероятно, что-то упускаю.

(Я определяю «регулярное выражение» в современном, нерегулярном смысле, т. Е. Используя все, что современные регулярные выражения имеют в своем распоряжении, такие как обратные ссылки и обходные пути.)

1 Ответ

2 голосов
/ 18 марта 2012

Цель регулярных выражений - описать синтаксис языка. Эти регулярные выражения затем можно использовать для поиска строк, соответствующих синтаксису этих языков. Вот и все.

То, что вы на самом деле делаете со спичками, зависит от ваших потребностей. Если вы ищете все совпадения, повторите процесс поиска и соберите совпадения. Если вы хотите разбить строку, повторите процесс поиска и разбейте входную строку в том месте, где найдены совпадения.

Таким образом, библиотеки регулярных выражений могут делать только одно: выполнять поиск совпадений. Все остальное - просто расширение.

Хорошим примером для этого является JavaScript, где есть RegExp.prototype.exec, который фактически выполняет поиск совпадений. Любой другой метод, который принимает регулярные выражения (например, RegExp.prototype.test, String.prototype.match, String.prototype.search), просто использует базовую функциональность RegExp.prototype.exec, так или иначе:

// pseudo-implementations
RegExp.prototype.test = function(str) {
    return RegExp(this).exec(str);
};
String.prototype.match = function(pattern) {
    return RegExp(pattern).exec(this);
};
String.prototype.search = function(pattern) {
    return RegExp(pattern).exec(this).index;
};
...