Управление окружающей средой функции

Пока на скриншоте строки выглядят так, как будто они находятся на постоянном уровне каждый,

они на самом деле не являются. Части «XXX ...:» и «TOTAL:» находятся в координатах y 469.45, 457.95 и 446.45, в то время как части «# ..», «1» и «2» находятся в координатах y 468.65, 457.15 и 445.65.

Чтобы рассматривать горизонтальный текст в одной строке, извлечение текста iText с использованием стратегии удаления текста по умолчанию (LocationTextExtractionStrategy) требует, чтобы y-координаты были одинаковыми после кастинга на int. (На самом деле это несколько упрощено, для всего изображения смотрите LocationTextExtractionStrategy.TextChunkLocationDefaultImp)

В данном случае это имеет место только для средней строки (int) 457.95 = 457 = (int) 457.15. Таким образом, извлечение текста по умолчанию приводит к:

XXXXXX XXXXX XXXXX : TOTAL :
#*2 1
XXXXXX XXXXX XXXXX : #*3 TOTAL : 2
XXXXXX XXXXX XXXXX: TOTAL :
#15 1

. В таких ситуациях вам нужна стратегия извлечения текста, которая распознает строки по-разному. Если вы, например, используйте HorizontalTextExtractionStrategy или HorizontalTextExtractionStrategy2 (в зависимости от вашей версии iText, первая для iText 5.5.8, последняя для нового iText 5.5.x версии) из этого ответа вы получите:

XXXXXX XXXXX XXXXX : #*2 TOTAL : 1
XXXXXX XXXXX XXXXX : #*3 TOTAL : 2
XXXXXX XXXXX XXXXX: #15 TOTAL : 1

(проверено с использованием метода TextExtraction.java testTest_pdf())


Кстати, это не означает, что по умолчанию следует переключиться на HorizontalTextExtractionStrategy2. Этот метод также имеет свои недостатки, в частности, он рассматривает всю ширину страницы (или, по крайней мере, всю страницу, если извлекать по фильтру), чтобы найти строки. Таким образом, если ваша страница, например. имеет два столбца текста nect друг к другу, а строки имеют одинаковую приблизительную высоту только за столбец, эта стратегия, скорее всего, вернет полный мусор.

Добавление

OP задал в комментарии

Можете ли вы дать мне краткое объяснение того, что делает HorizontalTextExtractionStrategy?

blockquote>

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

Когда его попросят получить результирующий текст, он в первом прогоне проецирует все эти ограничивающие прямоугольники на ось y системы координат страницы.

Во втором проходе он интерпретирует каждый подключенный компонент изображения этой проекции как диапазон координаты y одной строки: он выполняет итерацию по этим подключенным компонентам сверху вниз; для каждого компонента он принимает все куски, проецируемые в него, сортирует их по их координате x, добавляет места, где это необходимо, и объединяет их в текстовую строку.

Наконец, он возвращает конкатенацию этих строк (с линейными каналами

LocationTextExtractionStrategy говорит: « Этот рендерер отслеживает ориентацию и расстояние (как перпендикулярно, так и параллельно) единичному вектору ориентации. Текст упорядочивается по ориентация, затем перпендикуляр, затем параллельное расстояние. Текст с тем же перпендикулярным расстоянием, но с другим параллельным расстоянием рассматривается как находящийся на одной линии. «Это не имеет большого смысла для меня.

По сути, это также стратегия с двумя проходами, в первом проходе, собирающая все текстовые фрагменты с координатами, а во втором - размещение строк. Однако эта стратегия учитывает ориентацию базовой линии кусков и сначала сортирует по углу базовой линии.

Среди кусков с одинаковым базовым углом он считает, что куски принадлежат к одной и той же текстовой строке если их (ограниченные) базовые линии находятся на одной и той же (неограниченной) линии.

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

Сравнение, проведенное в соответствии с этой стратегией, основано на значениях int и поэтому допускает крошечный бит дисперсии

1
задан Rappster 15 January 2019 в 09:54
поделиться

2 ответа

Ах, я думаю, что поняла это сейчас.

Это связано со структурой формальных аргументов функции:

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

Один из способов запустить лексическую область видимости, даже если вы не хотите определять значение по умолчанию, - это установить значения по умолчанию «на лету» во время выполнения с помощью rlang::fn_fmls().

foo <- function(fun) {
  env_enclosing <- rlang::fn_env(fun)
  env_enclosing$x <- 5
  fun()
}

# No argument at all -> lexical scoping takes over
baz <- function() x
foo(baz)
#> [1] 5

# Set defaults to desired values on the fly at run time of `foo()`
foo <- function(fun) {
  env_enclosing <- rlang::fn_env(fun)
  env_enclosing$x <- 5
  fmls <- rlang::fn_fmls(fun)
  fmls$x <- substitute(get("x", envir = env_enclosing, inherits = FALSE))
  rlang::fn_fmls(fun) <- fmls
  fun()
}

bar <- function(x) x
foo(bar)
#> [1] 5
0
ответ дан Rappster 15 January 2019 в 09:54
поделиться

Я действительно не могу последовать вашему примеру, так как я незнаком с библиотекой rlang, но я думаю, что хорошим примером замыкания в R будет:

bucket <- function() {
    n <- 1
    foo <- function(x) {
        assign("n", n+1, envir = parent.env(environment()))
        n
    }
    foo
}
bar <- bucket()

, потому что bar() является определением в функциональной среде bucket его родительской средой является bucket, и поэтому вы можете перенести туда некоторые данные. Каждый раз, когда вы запускаете его, вы изменяете среду bucket:

bar()
[1] 2
bar()
[1] 3
bar()
[1] 4
0
ответ дан trosendal 15 January 2019 в 09:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: