#javascript #string #substring
#javascript #строка #подстрока
Вопрос:
У меня есть строка, которая может содержать различные биты информации, мне нужно подстрочить GUID из этого, когда я не могу быть уверен в позиции GUID в строке.
Возможные версии строки
stringVar=email:name@company.com amp;номер:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6;
stringVar=email:name@company.com amp;номер:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6amp;host=ИМЯ ХОСТА;
stringVar=email:name@company.comamp;location=SomeCity amp;номер:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6;
Существует несколько других перестановок строки с большим или меньшим количеством полей, она всегда будет, по крайней мере, содержать GUID.
Приблизительная версия того, что у меня есть:
var room = str.substring(str.lastIndex(room),str.lastIndex(;))
if room.length !== 36
var room = str.substring(str.lastIndex(room),str.lastIndexOf(amp;)
Должен быть более чистый способ сделать это?
Комментарии:
1. Я бы предпочел использовать регулярное выражение, если входная строка иногда меняется
2. Другой способ использовать регулярное выражение
stringVar.match(/room:([a-zA-Z0-9-] )/)[1]
3. Почему у какой-то пары ключ-значение есть
=
, а у какой-то есть:
. Это намеренно?4. @Rajesh на самом деле это переменная cookie проприетарной системы, поэтому я, к сожалению, застрял с ней.
5. @haddow64 Я попытался добавить универсальную функцию для анализа вашего формата. Не идеально, но должно помочь.
Ответ №1:
Должен быть более чистый способ сделать это?
Существует — REGEX.
var guid = str.match(/room:([^amp;] )/);
Совпадение, если оно найдено, будет сохранено в guid[0]
, только с идентификатором guid (минус «room:») в guid[1]
.
Комментарии:
1. Спасибо, хороший и понятный способ сделать это.
Ответ №2:
Вы можете просто использовать манипулирование строками, например:
var stringVar1 = "email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6";
var stringVar2 = "email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6amp;host=HOSTNAME";
var stringVar3 = "email:name@company.comamp;location=SomeCityamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6";
function getRoomId(input) {
return input
.split("amp;") //separate into chunks
.find(part => part.startsWith("room:")) //see which starts with room
.split(":")[1]; //split and return the second part, which is the GUID
}
console.log(getRoomId(stringVar1));
console.log(getRoomId(stringVar2));
console.log(getRoomId(stringVar3));
Альтернативно, более «тупой» способ — просто обрезать нужную строку. Основным недостатком является то, что это выглядит не так «модно», но, с другой стороны, это будет работать во всех браузерах.
var stringVar1 = "email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6";
var stringVar2 = "email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6amp;host=HOSTNAME";
var stringVar3 = "email:name@company.comamp;location=SomeCityamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6";
function getRoomId(input) {
return input
.split("room:")[1] //find the part of the string that starts with "room:" and cut there
.split("amp;", 1)[0]; //cut again at the next "amp;" and return the first part
}
console.log(getRoomId(stringVar1));
console.log(getRoomId(stringVar2));
console.log(getRoomId(stringVar3));
Наконец, вы можете выполнить еще более простой поиск значений, который также будет работать во всех браузерах:
var stringVar1 = "email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6";
var stringVar2 = "email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6amp;host=HOSTNAME";
var stringVar3 = "email:name@company.comamp;location=SomeCityamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6";
function getRoomId(input) {
var start = input.indexOf("room:") 5; //the index is the beginning of "room:", so add 5 characters to get rid of it
var end = input.indexOf("amp;", start); //the next "amp;" after "room:" will be after the GUID
end = end !== -1? end : input.length; //if there is no next "amp;", then grab everything until the end of the string
return input.slice(start, end);
}
console.log(getRoomId(stringVar1));
console.log(getRoomId(stringVar2));
console.log(getRoomId(stringVar3));
Существуют и другие варианты, но идея в том, что это достаточно просто решить, обработав это как строку.
Ответ №3:
Используйте это регулярное выражение
/(room:[a-zA-Z0-9] -[a-zA-Z0-9] -[a-zA-Z0-9] -[0-9] -[a-zA-Z0-9] )/
это соответствовало бы следующим данным:
room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6
room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6
room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6
Вот соответствие: демо
Ответ №4:
Ваш guid ‘room’ содержит только шестнадцатеричные символы. Используйте простое регулярное выражение соответствия, чтобы получить то, что вам нужно:
/amp;room:([a-fd-] )/i
и если room
может отображаться как первое поле в строке (в ее начале), вы можете улучшить его, чтобы оно также соответствовало началу строки:
/(?:^|amp;)room:([a-fd-] )/i
^^^^
Смотрите демонстрацию регулярных выражений
Подробные сведения:
amp;room:
— соответствует буквенной последовательности символовamp;room:
((?:^|amp;)
это группа чередований, соответствующая либо начальной позиции строки (^
), либо (|
)amp;
символу)([a-fd-] )
— сопоставляет и захватывает в группу 1 один или более символов, которые являются буквами ASCII в диапазонахa-f
иA-F
(поскольку/i
модификатор режима не учитывает регистр), цифр (d
) или-
.
var strngs = ['stringVar=email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6;', 'stringVar=email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6amp;host=HOSTNAME;', 'stringVar=email:name@company.comamp;location=SomeCityamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6;'];
var re = /amp;room:([a-fd-] )/i;
for (var s of strngs) {
var res = (m=s.match(re)) ? m[1] : "";
console.log(s "n=>n" res); // demo
}
Ответ №5:
var str = "email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6;";
var room = str.split("room:")[str.split("room:").length-1].split("amp;")[0].split(";")[0];
//b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6
Комментарии:
1. Вы можете использовать
.pop
вместо[str.split("room:").length-1]
Ответ №6:
Я попытался создать функцию, которая возвращала бы вам объект.
Примечание: Я немного изменил формат. Я добавил city:SomeCity
в третьем формате.
Базовый формат заключается в том, что у вас может быть =
который будет иметь либо строковое значение, либо объект, но не оба сразу. Итак, amp;host=HOSTNAME
это нормально, но location=SomeCityamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6
это не так, и я изменил ее на location=city:SomeCityamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6;
Точка — это значение после того, как оно =
должно либо содержаться :
для каждой пары, либо его нет.
Пример
function getObjectFromCookieStr(str){
var r = {};
str.split("=").reduce(function(p,c){
var k = ''
var o = c.split('amp;').reduce(function(p,c){
if(c.indexOf(':') > -1){
var kv = c.split(':');
p[kv[0]] = kv[1]
}
else{
k=c;
}
return p;
}, {});
r[p] = Object.keys(o).length >0 ? o : c
return k;
});
return r;
}
var s1 = "stringVar=email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6"
var s2 = "stringVar=email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6amp;host=HOSTNAME";
var s3 = "stringVar=email:name@company.comamp;location=city:SomeCityamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6";
console.log(getObjectFromCookieStr(s1))
console.log(getObjectFromCookieStr(s2))
console.log(getObjectFromCookieStr(s3))
Теперь, когда у нас есть объект, вам просто нужно выполнить цикл над объектом, чтобы получить значение. Вы можете использовать следующую функцию для поиска в объекте.
function searchKeyInObj(obj, searckKey) {
if (JSON.stringify(obj).indexOf(searckKey) < 0) return;
for (var k in obj) {
if (typeof(obj[k]) === 'object') {
var v = searchKeyInObj(obj[k], searckKey);
if (v) return v
} else if (k === searckKey) {
return obj[k];
}
}
}
Вы можете протестировать ее на следующем JSFiddle
Ответ №7:
Регулярное выражение — хороший вариант, но это затрудняет чтение кода.
var stringValue = "stringVar=email:name@company.comamp;room:b83edd0d-fec5-4ec0-8055-60bc0d8eb4b6amp;host=HOSTNAME;"
var pattern = /[da-zA-Z]{8}-([da-zA-Z]{4}-){3}[da-zA-Z]{12}/;
var found = stringValue.match(pattern)
console.log(found[0]);
Этот фрагмент кода принимает строковое значение и выполняет простое сопоставление с использованием выражения Regex, это возвращает результирующий массив, я просто беру первое значение индекса из результирующего массива.