Если строка будет содержать данные Unicode (строго говоря, non-BMP символы) другие методы, которые были отправлены, то повредит его, потому что Вы не можете подкачать порядок высоких и низких суррогатных элементов кода при инвертировании строки. (Больше информации об этом может быть найдено на мой блог .)
следующий пример кода правильно инвертирует строку, которая содержит non-BMP символы, например, "\U00010380\U00010381" (угаритская Буква Alpa, угаритская Бета Буквы).
public static string Reverse(this string input)
{
if (input == null)
throw new ArgumentNullException("input");
// allocate a buffer to hold the output
char[] output = new char[input.Length];
for (int outputIndex = 0, inputIndex = input.Length - 1; outputIndex < input.Length; outputIndex++, inputIndex--)
{
// check for surrogate pair
if (input[inputIndex] >= 0xDC00 && input[inputIndex] <= 0xDFFF &&
inputIndex > 0 && input[inputIndex - 1] >= 0xD800 && input[inputIndex - 1] <= 0xDBFF)
{
// preserve the order of the surrogate pair code units
output[outputIndex + 1] = input[inputIndex];
output[outputIndex] = input[inputIndex - 1];
outputIndex++;
inputIndex--;
}
else
{
output[outputIndex] = input[inputIndex];
}
}
return new string(output);
}
Я удивлен, не увидев здесь собственного решения для bash. Да, в bash есть регулярные выражения. Вы можете найти множество произвольной документации в Интернете, особенно если вы включите «bash_rematch» в свой запрос или просто посмотрите страницы руководства. Вот глупый пример, взятый из здесь и немного измененный, который печатает все совпадение и каждое из захваченных совпадений для регулярного выражения.
if [[ $str =~ $regex ]]; then
echo "$str matches"
echo "matching substring: ${BASH_REMATCH[0]}"
i=1
n=${#BASH_REMATCH[*]}
while [[ $i -lt $n ]]
do
echo " capture[$i]: ${BASH_REMATCH[$i]}"
let i++
done
else
echo "$str does not match"
fi
Важным моментом является то, что расширенный тест [[...
Если вы хотите сделать это в Bash, вы можете сделать что-то вроде следующего. Он использует подстановку вместо регулярных выражений (параметр оболочки extglob
включает расширенное сопоставление с образцом, так что мы можем сопоставить строку, состоящую только из звездочек.)
#!/bin/bash
shopt -s extglob
entry=""
while read line
do
case $line in
+(\*))
# do something with $entry here
entry=""
;;
*)
entry="$entry$line
"
;;
esac
done
Попробуйте заключить команду в двойные кавычки.
#!/bin/bash
for error in "`python example.py | sed -n '/.*/,/^\**$/p'`"
do
echo -e $error
echo -e "\n"
done
в зависимости от того, что вы хотите сделать с переменными
awk '
f && /\*/{print "variable:"s;f=0}
/\*/{ f=1 ;s="";next}
f{
s=s" "$0
}' file
, вывод:
# ./test.sh
variable: Field1
variable: Lorem ipsum Data to match
variable: More data Still more data
приведенный выше просто выводит их. если хотите, сохраните в массиве для дальнейшего использования ... например, array [++ d] = s
Разделение записей в (ba) sh не так просто, но может быть выполнено с помощью IFS для разделения на отдельные символы (просто установите IFS = '*' перед циклом for, но это приведет к созданию нескольких пустые записи и проблематично, если какая-либо запись содержит '*'). Очевидное решение - использовать perl или awk и использовать RS для разделения ваших записей, поскольку эти инструменты предоставляют лучшие механизмы для разделения записей. Гибридное решение - использовать Perl для разделения записей и заставить Perl вызывать вашу функцию bash с нужной записью. Например:
#!/bin/bash
foo() {
echo record start:
echo "$@"
echo record end
}
export -f foo
perl -e "$/='********'; while(<>){chomp;system( \"foo '\$_'\" )}" << 'EOF'
this is a 2-line
record
********
the 2nd record
is 3 lines
long
********
a 3rd * record
EOF
Это дает следующий результат:
record start: this is a 2-line record record end record start: the 2nd record is 3 lines long record end record start: a 3rd * record record end