Sas убрать пробелы в строке
CALL SYMPUT
Call Symput используется для случаев, когда значение переменной в шаге данных (datastep) нужно присвоить макропеременной.
Синтаксис: call symput ("", )
Первый аргумент в процедуре symput — это название макропеременной, которой необходимо присвоить значение второго аргумента.
Пример:
data _null_;
count=1978;
call symput('count',count);
run;
%put &count;
19 data _null_;
20 count=1978;
21 call symput('count',count);
22 run;
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
21:21
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds
Хоть значение макропеременной count и было определено как 1978, SAS выдал замечание, гласящее
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
21:21
Чтобы избежать этого, Вам всё же стоит осуществить конвертирование численного значения в символьное, прежде чем присваивать его макропеременной. Вот, например, как это можно сделать:
data _null_;
count=1978;
call symput('count',strip(put(count,8.)));
run;
%put &count;
29 data _null_;
30 count=1978;
31 call symput('count',left(put(count,8.)));
32 run;
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
- Несмотря на то, что мы создали переменную при помощи CALL SYMPUT , эта макропеременная не может быть использована напрямую в том же datastep'е. Причина такого явления — макро код компилируется и выполняется до того, как будет скомпилирован и выполнен datastep. Так что, макропеременная, создающаяся CALL SYMPUT , не будет доступна в datastep в силу того, что эта макропеременная будет создана и присвоена только после или во время выполнения кода datastep.
(В случае, если Вам всё же понадобится доступ к той же макропеременной внутри datastep, Вы, разумеется, сумеете это сделать, при помощи двух разных макрофункций — RESOLVE или SYMGET ) - SAS всегда выравнивает численные значения по правому краю, что приводит к пробелам в начале символьной переменной при конвертации, если значение численной переменной было меньше её длины. Чтобы избавиться от этих пробелов, используйте функции, удаляющие все ведущие пробелы (как в примере выше).
- Если процедура CALL SYMPUT используется вне макроса (т.е. в открытом коде), она создаёт глобальную макропеременную, тогда как при использовании внутри макроса она создаст локальную.
CALL SYMPUTX
- SYMPUTX автоматически конвертируют численные переменные в символьные перед присваиванием их макропеременной. (Вы больше не нуждаетесь в ручной конвертации при помощи выраждения PUT как в вышеприведённом примере)
- CALL SYMPUTX удаляет ведущие и хвостовые пробелы. Так что необходимость функций, наподобие STRIP или LEFT , для очистки от лишних пробелов, отпадает.
Первые два аргумента аналогичны аргументам CALL SYMPUT . Третий аргумент (таблица символов) опционален и может принимать значения G, L или F. Если Вы укажете G, макропеременная будет создана в глобальной таблице символов, если же Вы укажете L, SAS сохранит макропеременную в локальной таблице. Если третий аргумент не указывать или установить его как F, CALL SYMPUTX будет вести себя аналогично CALL SYMPUT .
Пример:
data _null_;
count=1978;
call symputx('count',count,’G’);
run;
%put &count;
29 data _null_;
30 count=1978;
31 call symputx('count',count,'G');
32 run;
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
33 %put &count;
1978
Примечание: Если бы Вы использовали CALL SYMPUT вместо CALL SYMPUTX , программа выполнилась бы идентично, но в лог было бы выдано замечание об автоматической конвертации численного значения в символьное.
Процедура SAS V9 CALL SYMPUTX позволяет Вам сэкономить нажатия клавиш и создать более компактный и понятный код.
Вместо использования
call symput('macrovar', trim(left(charvar)));
для создания макропеременной с символьной строкой, которая может содержать лишние пробелы, Вам стоит применить SYMPUTX:
call symputx('macrovar', charvar);
Учитывая строку, содержащую много последовательных пробелов, обрежьте все пробелы так, чтобы все слова содержали только один пробел между ними. Преобразование должно быть выполнено на месте, и решение должно обрабатывать конечные и начальные пробелы, а также удалять предшествующие пробелы перед обычной пунктуацией, такой как точка, запятая и вопросительный знак.
Идея состоит в том, чтобы поддерживать 2 указателя. Первоначально оба указывают на начало массива.
Первый указатель отслеживает следующую позицию, которая будет заполнена в выходной строке.
Второй указатель используется для чтения всех символов строки один за другим.
При нахождении любого непробельного символа этот символ копируется в местоположение первого указателя, а затем передаются как первый, так и второй указатели.
Если непробельный символ — точка, запятая или вопросительный знак, мы также удаляем все предшествующие пробелы перед ним.
При нахождении последовательных пробельных символов один единственный пробел копируется в местоположение первого указателя, а остальные игнорируются. Начальные и конечные пробелы обрабатываются отдельно в решении.
Ниже приведена реализация вышеуказанной идеи на C ++.
using namespace std;
// Функция обрезки всех пробелов в
// строка такая, что все слова должны содержать только
// один пробел между ними.
void removeSpaces(string &str)
// n - длина исходной строки
int n = str.length();
// я указываю на следующую позицию для заполнения
// выводим строку / j указывает на следующий символ
// в исходной строке
// устанавливается значение true, если пробел найден
bool spaceFound = false ;
// Обрабатывает ведущие пробелы
// читаем все символы оригинальной строки
// если текущие символы не пробелы
// удаляем предшествующие пробелы перед точкой,
// запятая и вопросительный знак
str[j] == '?' ) && i - 1 >= 0 &&
// копировать текущий символ по индексу i
// и увеличиваем как i, так и j
// устанавливаем флаг пробела в false когда любой
// найден непробельный символ
// если текущий символ пробел
// Если пробел встречается для первого
// время после слова, ставьте один пробел в
// выводим и устанавливаем флаг пробела в true
// Удалить конечные пробелы
str.erase(str.begin() + i, str.end());
str.erase(str.begin() + i - 1, str.end());
string str = " Hello Geeks . Welcome to"
Временная сложность вышеуказанного решения составляет O (n).
Вспомогательное пространство равно O (1), поскольку преобразование выполняется на месте.
Другое решение, использующее предопределенные функции в Python 3:
' Hello Geeks . Welcome , Do you love Geeks , Geeks ? '
for index in range ( len (input_string)):
if space_flag = = True :
elif input_string[index - 1 ] ! = ' ' :
Временная сложность вышеуказанного решения составляет O (n).
Вспомогательное пространство — O (n), поскольку другой список должен был быть создан.
Другой подход: (с использованием встроенной функции)
/ **
Java-программа для удаления лишних пробелов из строки
** /
public class GFG
public static void main(String args[])
String str = " Hello Geeks . Welcome , Do you love Geeks , Geeks ? " ;
System.out.println(str.replaceAll( "\\s+" , " " ).trim());
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
Получив строку, удалите все пробелы из строки и верните ее.
Ожидаемая сложность времени O (n) и только один обход строки.
Мы настоятельно рекомендуем вам нажать здесь и попрактиковаться, прежде чем переходить к решению.
Ниже приведено простое решение
Временная сложность вышеуказанного решения составляет O (n 2 ).
Лучшее решение может решить это за O (n) время. Идея состоит в том, чтобы отслеживать количество непробельных символов, замеченных до сих пор.
Ниже приведена реализация вышеуказанного алгоритма.
using namespace std;
// Функция для удаления всех пробелов из заданной строки
void removeSpaces( char *str)
// Отслеживать количество символов без пробелов
// Обход заданной строки. Если текущий персонаж
// не пробел, затем поместите его в индекс 'count ++'
for ( int i = 0; str[i]; i++)
str[count++] = str[i]; // здесь количество
// Программа драйвера для проверки вышеуказанной функции
char str[] = "g eeks for ge eeks " ;
// Эффективная Java-программа для удаления всех пробелов
// из строки
// Функция для удаления всех пробелов
// из заданной строки
static int removeSpaces( char []str)
// Отслеживать количество символов без пробелов
// Обход заданной строки.
// Если текущий символ
// это не пробел, то место
// это по индексу 'count ++'
str[count++] = str[i]; // здесь количество
public static void main(String[] args)
char str[] = "g eeks for ge eeks " .toCharArray();
int i = removeSpaces(str);
System.out.println(String.valueOf(str).subSequence( 0 , i));
// Этот код предоставлен Rajput-Ji
for i in xrange ( len (string)):
return toString( list )
def toString( List ):
return ''.join( List )
string = "g eeks for ge eeks "
// Функция для удаления всех пробелов
// из заданной строки
static int removeSpaces( char []str)
// Для отслеживания не пробелов
// Обход заданной строки. Если текущий
// символ не пробел, затем место
// это по индексу 'count ++'
str[count++] = str[i]; // здесь количество
public static void Main(String[] args)
char []str = "g eeks for ge eeks " .ToCharArray();
int i = removeSpaces(str);
Console.WriteLine(String.Join( "" , str).Substring(0, i));
// Этот код предоставлен 29AjayKumar
Временная сложность вышеуказанного решения составляет O (n), и он выполняет только один обход строки.
Другим решением, предложенным Divyam Madaan, является использование предопределенных функций. Вот реализация:
// Программа CPP для удаления пробелов
// из заданной строки
using namespace std;
// Функция для удаления всех пробелов из заданной строки
string removeSpaces(string str)
str.erase( remove (str.begin(), str.end(), ' ' ), str.end());
// Программа драйвера для проверки вышеуказанной функции
string str = "g eeks for ge eeks " ;
// Этот код предоставлен Divyam Madaan
// Java-программа для удаления
// все пробелы из строки
// Функция для удаления всех
// пробелы из заданной строки
static String removeSpace(String str)
str = str.replaceAll( "\\s" , "" );
public static void main(String args[])
String str = "g eeks for ge eeks " ;
// Этот код предоставлен Kanhaiya.
string = "g eeks for ge eeks "
// Функция для удаления всех
// пробелы из заданной строки
static String removeSpace(String str)
public static void Main()
String str = "g eeks for ge eeks " ;
// Этот код предоставлен
// PrinciRaj1992
Спасибо Сурави Саркару за предложение этой проблемы и первоначальное решение.
Java | Удаление пробелов с помощью Regex
Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме
Я пытаюсь удалить начальные и конечные пробелы во 2-м столбце нижеследующего input.txt :
Name, Order
Trim, working
cat,cat1
Я использовал приведенный ниже awk , чтобы удалить начальные и конечные пробелы во 2-м столбце, но это не работает. Что мне не хватает?
Это дает результат как:
Name, Order
Trim, working
cat,cat1
Начальные и конечные пробелы не удаляются.
Если вы хотите обрезать все пробелы, только в строках с запятыми, и использовать awk , то для вас подойдет следующее:
Если вы хотите удалить пробелы только во втором столбце, измените выражение на
Обратите внимание, что gsub заменяет символ в // вторым выражением в переменной, которая является третьим параметром - и делает это in-place - другими словами, когда это сделано, $0 (или $2 ) был изменен.
EDIT Я хочу отметить, что решение @BMW лучше, поскольку оно фактически удаляет только начальные и конечные пробелы двумя последовательными командами gsub . Отдавая должное, я объясню, как это работает.
Если можно безопасно принять только один набор пробелов во втором столбце (который является исходным примером):
Добавление еще одного поля, например awk '' /tmp/input.txt поймает два набора пробелов (до трех слов во втором столбце) и не сломается, если их будет меньше.
Если у вас неопределенное (большое) количество слов, разделенных пробелами, я бы использовал одно из предыдущих предложений, в противном случае это решение будет самым простым, которое вы найдете при использовании awk.
Кажется, работает следующее:
Самое простое решение - использовать tr
Просто используйте регулярное выражение в качестве разделителя:
', *' - для ведущих пробелов
'*,' - для завершающих пробелов
Как для ведущих, так и для конечных:
Я только что наткнулся на это. Правильный ответ:
Предупреждение от @Geoff: см. Мою заметку ниже, работает только одно из предложений в этом ответе (хотя и для обоих столбцов).
Я бы использовал sed :
Будет удален начальный пробел после , . Выход:
В более общем плане может быть следующее: возможно, несколько пробелов и / или табуляции после , будут удалены:
Он также будет работать с более чем двумя столбцами из-за глобального модификатора /g
@Floris попросил в обсуждении решение, которое удаляет конечные и конечные пробелы в каждом столбце (даже первом и последнем), не удаляя пробелы в середине столбца:
* EDIT by @Geoff, я добавил имя входного файла к этому, и теперь он удаляет только все начальные и конечные пробелы (хотя из обоих столбцов). Другие предложения в этом ответе не работают. Но попробуйте: «Несколько пробелов и два пробела перед здесь» *
IMO sed - оптимальный инструмент для этой работы. Однако здесь есть решение с awk , потому что вы просили об этом:
У меня есть образец набора данных, как показано ниже.
Я хочу экспортировать этот набор данных в csv (формат с фиксированной шириной), и каждая строка будет иметь длину 20 байт (20 однобайтовых символов).
Но SAS автоматически удаляет мои конечные пробелы. Таким образом, результат будет 17 байт для каждой строки. (наполнитель усеченный)
Я знаю, что могу вставить наполнитель вот так.
Но это не сработает, если столбец site пуст, SAS обрежет этот столбец, и результат также не будет равен 20 байтам для каждой строки.
Этот выходной формат НЕ является файлом CSV. Он не имеет значений, разделенных запятыми. Это даже не файл с разделителями, это файл фиксированного формата. Вероятно, вы НЕ хотите использовать многобайтовый набор символов с файлом фиксированного формата именно по той причине, по которой у вас возникли проблемы.
@Tom Спасибо за ответ. На самом деле расширение файла на самом деле не связано с форматом файла. Но требуется экспортировать файл формата фиксированной ширины в файл csv-extension. Я знаю, что многобайтовый набор символов вызывает проблему, но у меня нет другого выбора, используя SAS 9.4 University Edition, я не могу изменить кодировку сеанса, но придерживаюсь кодировки UTF-8 по умолчанию.
Я просто предупреждал вас, что любые программы, которые попытаются прочитать этот файл, будут иметь те же проблемы с чтением файла, что и ваша программа SAS при записи файла. Кроме того, вы используете расширение для своего имени файла, что вызовет путаницу, поскольку это означает, что файл определенного типа, а файл, который вы создаете, НЕ находится в этом формате.
Я не совсем понял, что вы пытаетесь сделать с помощью ksubstr, но если вы хотите добавить отступ, чтобы получить общую длину до 20 символов, вам, возможно, придется написать дополнительную логику:
Сработало отлично. Большое спасибо. Причина для ksubstr заключается в том, что японский символ имеет 3 байта в SAS, поэтому я не могу использовать стандартную функцию substr, чтобы гарантировать, что длина выходной строки составляет 17 символов (байтов)
Причина использования серии функций K . заключается в том, что они подсчитывают количество символов ВМЕСТО обычных функций, которые просто подсчитывают количество байтов.
@PythonRSAS Я хочу убедиться, что выходное значение столбца Name будет 5 символов (включая пробелы, если они есть).
Вероятно, вы не захотите записывать файл с фиксированным столбцом, используя многобайтовый набор символов. Вместо этого посмотрите, можете ли вы настроить свой процесс, чтобы вместо этого использовать файл с разделителями. Как и в вашем примере входных данных.
Если вы хотите, чтобы функция PUT записывала определенное количество байтов, просто используйте форматированный оператор PUT. Чтобы количество записанных байтов варьировалось в зависимости от значения строки, вы можете использовать формат $ VARYING. Синтаксис при использовании $ VARYING немного отличается от синтаксиса при использовании обычных форматов. Вы добавляете вторую ссылку на переменную после спецификации формата, которая содержит фактическое количество байтов для записи.
Вы можете использовать функцию LENGTH (), чтобы вычислить, сколько байтов занимают ваши значения имени. Поскольку он обычно игнорирует конечный пробел, просто добавьте еще один символ в конец и вычтите его из общей длины.
Чтобы заполнить конец тремя пробелами, вы можете просто добавить три к ширине, используемой в формате для последней переменной.
Читайте также: