Javascript составной RegExp, содержащий суб-RegExps - PullRequest
1 голос
/ 15 марта 2019

Я написал RegExp, который корректно проверяет одну валюту, например. EUR или USD:

const ccyRegEx = new RegExp(currencies.join('|'), 'i');

, который производит что-то вроде EUR|USD|JPY|GBP..., данное currencies = ["EUR", "USD", "JPY", "GBP"...]

Как бы я мог использовать этот RegExp и массив currencies в качестве входных данных для создания нового RegExp, который проверяет валютные пары, например. EURUSD, USDJPY?

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

Одинаковые валютные пары, например, EUREUR и USDUSD НЕ действительны.
Действительны валютные пары в разных ордерах, например EURUSD и USDEUR.

Ответы [ 3 ]

3 голосов
/ 15 марта 2019

Вы можете просто добавить {2}, чтобы точно соответствовать двум элементам вашего набора.

Например, /(a|b|c){2}/ будет соответствовать ab, ca, но не ad.

Вы можете изменить свое динамическое регулярное выражение следующим образом:

const currencies = ["EUR", "USD", "JPY", "GBP"];
const singleMatch = new RegExp(currencies.join('|'));

console.log('single match - EUR:', singleMatch.test('EUR'));

const doubleMatch = new RegExp('(' + currencies.join('|') + '){2}');


console.log('double match - EUR:', doubleMatch.test('EUR'));
console.log('double match - USDEUR:', doubleMatch.test('USDEUR'));
console.log('double match - GBPEUR:', doubleMatch.test('GBPEUR'));
console.log('double match - GBPGDD:', doubleMatch.test('GBPGDD'));

Обратите внимание: это также соответствует EUREUR. Чтобы избежать этого, вы должны использовать отрицательный прогноз или негативный прогноз.


Редактировать

Я интегрирую реализацию @PJProudhon негативного прогнозирования, как он заявил в разделе комментариев:

const currencies = ["EUR", "USD", "JPY", "GBP"];
const doubleMatch = new RegExp('(?:(' + currencies.join('|') + ')(?!\\1)){2}');

console.log('double match - EUREUR:', doubleMatch.test('EUREUR')); //expect false

Спасибо @ PJProudhon

2 голосов
/ 15 марта 2019

Я бы сказал, чтобы это было просто глупо, и создавал промежуточный массив со всеми возможностями, например:

const currenciesPair = [];
const currenciesLength = currencies.length

for (let i = 0; i < currenciesLength ; i++) {

    for (let j = 0; j < currenciesLength ; j++) {
        // avoiding pair such as EUREUR, USDUSD, etc...
        if (i !== j) {
            currenciesPair.push(currencies[i] + currencies[j]);
        }
    }
}

И сохраните свое регулярное выражение с этим массивом (вы также можете смешивать валютыPair и валюты для полных возможностей):)

1 голос
/ 15 марта 2019

Это довольно неэффективный алгоритм, поэтому, в зависимости от количества валют, другие варианты будут лучше.

Если это возможно для набора данных, я бы предпочел решение Кристиана Траина.

const currencies = [ "EUR", "USD", "JPY", "GBP" ];

const product_matrix = currencies // loop over all the currencies
	.map( currency => currencies // We want to join the currency with all other currencies
		.map( pair => currency !== pair // Only do the join if the currency and its pair aren't the same
			? `${ currency }${ pair }`
			: null )
		.filter( Boolean ) // Remove all the null values. YOu coudl use reduce instead of map to skip this step.
	)
	.flat(); // Flatten the 2 dimensional array into a one dimensional one.
	
console.log( product_matrix );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...