Получить строку между двумя конкретными позициями символов

У меня есть длинная текстовая строка в SAS, и значение внутри него переменной длины, но всегда сопровождается символом "#" и затем заканчивается символом ","

Есть ли способ, которым я могу извлечь это и сохранить как новую переменную, пожалуйста?

например: слово слово, слово, № 12.34, слово, слово

И я хочу получить 12,34

Спасибо!

5 ответов

Двойное сканирование также должно работать, если у вас есть только один #:

data _null_;
  var1 = 'word word, word, #12.34, word, word';
  var2 = scan(scan(var1,2,'#'),1,',');
  put var2=;
run;

Вы можете использовать substr а также index функции, чтобы сделать это. index функция возвращает первую позицию указанного символа.

data _null_;
var1 = 'word word, word, #12.34, word, word';
pos1 = index(var1,'#'); *Get the position of the first # sign;
tmp = substr(var1,pos1+1); *Create a string that returns only characters after the # sign;
put tmp;
pos2 = index(tmp,','); *Get the position of the first "," in the tmp variable;
var2 = substr(tmp,1,pos2-1);
put var2;
run;

Обратите внимание, что этот метод работает, только если в строке есть только один "#".

Еще один способ сделать это с помощью Regex и код приведен ниже

data have;
infile datalines truncover ;
input var $200.;
datalines;
word word, word, #12.34, word, word
word1 #12.34, hello hi hello hi
word1 #970000 hello hi hello hi #970022, hi
word1 123,  hello hi hello hi #97.99
#99456, this is cool
 ;

Небольшая заметка о ниже регулярных выражений и функций

(?<=#) Позитивное утверждение с нулевой шириной и поиск # перед образцом интереса

(\d+.?\d+) здесь означает цифру, за которой следует или не следует. и другие цифры

(?=,) Позитивное упреждающее утверждение нулевой ширины и поиск по интересующему образцу

Вызов prxsubstr находит положение и длину шаблона, а substr извлекает требуемые значения.

 data want( drop=pattern position length);
 retain pattern;
 IF _N_ = 1 THEN PATTERN = PRXPARSE("/(?<=#)(\d+\.?\d+)(?=,)/");
 set have;
call prxsubstr(pattern, var, position, length);
if position then
  match = substr(var, position, length);    
 run;

Одним из способов является использование index определить местонахождение двух "стражей", разграничивающих значение, и получить данные с помощью substr, Если значение должно быть числовым, дополнительное использование input функция нужна.

Второй способ заключается в использовании регулярных выражений prxmatch а также prxposn найти и извлечь вложенное значение.

data have;
  input; 
  longtext = _infile_;
datalines;
some thing #12.34, wicked
#, oops
#5a64, oops
# oops
oops ,
oops #
ok #1234,
who wants be a #1e6,aire
space #   , the final frontier
double #12, jeopardy #34, alex
run;

data want;
  set have;

  * locate with index;

  _p1 = index(longtext,'#');
  if _p1 then _p2 = index(substr(longtext,_p1),',');
  if _p2 > 2 then num_in_text = input (substr(longtext,_p1+1,_p2-2), ?? best.);

  * locate with regular expression;

  if _n_ = 1 then _rx = prxparse('/#(\d*\.?\d*)?,/'); retain _rx;
  if prxmatch(_rx,longtext) then do;
    call prxposn(_rx,1,_start,_length);
    if _length > 0 then num_in_text_2 = input (substr(longtext,_start, _length), ?? best.);
  end;

  * drop _: ;
run;

Путь регулярного выражения ищет варианты ##.##, путь индекса ищет только #...,. Затем входная функция расшифрует значения научной нотации, которые регулярное выражение (пример шаблона) не найдет. ?? вариант в input Функция предотвращает недопустимые аргументы. ПРИМЕЧАНИЕ:s в журнале, когда вложенное значение не может быть проанализировано как число.

Если вы хотите стать очень ленивым, вы можете просто сделать

want = compress(have,".","kd");
Другие вопросы по тегам